Rxjava輔助操作符

Rxjava操作符索引

這篇章主要介紹Rxjava的輔助操作符

目錄

Delay

Do

Serialize

TimeInterval

Timeout

Timestamp

To

Using


Delay

延遲一段指定的時間再發射來自Observable的發射物

Observable.just(1,2,3).delay(2000, TimeUnit.MILLISECONDS, Schedulers.trampoline()).subscribe(num -> System.out.println(num+""));

結果:

1
2
3

上面的結果是延遲兩秒發射,注意是每個數據都延遲了兩秒發射。

一參爲延遲的時間,二參爲時間單位,三參爲調度器表示在哪個線程調度。

Do

這系列操作符有好幾個,我只寫一個,後面都很容易明白了。

Observable.just(1,2,3)
                .doOnNext(num ->System.out.println(num+"++"))
                .subscribe(num -> System.out.println(num+"*"));

結果:

1++
1*
2++
2*
3++
3*

看上面的結果,一分析就明白了。doOnNext就是在onNext輸出前,執行你寫的操作。下面還有do的其他操作符

doOnSubscribe :訂閱前調用

doOnUnsubscribe:不訂閱前調用

doOnCompleted :完成前調用

doOnError:異常終止前調用 

 doOnTerminate:終止前調用,不管completed還是error 

finallyDo: 終止後調用,不管completed還是error 

Serialize

一個Observable可以異步調用它的觀察者的方法,可能是從不同的線程調用。這可能會讓Observable行爲不正確,它可能會在某一個onNext調用之前嘗試調用onCompletedonError方法,或者從兩個不同的線程同時調用onNext方法。

這個暫時不寫例子,以後補上。看到這裏的朋友,也可以自己試一下寫demo,我也渴望參詳參詳。

TimeInterval

TimeInterval操作符攔截原始Observable發射的數據項,替換爲發射表示相鄰發射物時間間隔的對象。

 Observable.create(new ObservableOnSubscribe<String>() {
            @Override
            public void subscribe(ObservableEmitter<String> observableEmitter) throws Exception {
                for (int i = 0; i < 3; i++){
                    try {
                        Thread.sleep(1000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    observableEmitter.onNext(i+"");
                }
                observableEmitter.onComplete();
            }
        }).timeInterval(Schedulers.trampoline())
                .subscribe(new Consumer<Timed<String>>() {
                    @Override
                    public void accept(Timed<String> stringTimed) throws Throwable {
                        System.out.println(stringTimed.value() +"::" +stringTimed.time());
                    }
                });

結果:

0::1005
1::1000
2::1009

timeInterval操作符,可以讓我們發射的數據轉換成Timed<?>類,這個對象的value()爲我們發射的數據的值,time()爲上一個數據和這個數據發射間的時間間隔(單位:毫秒),而第一項數據得到的時間爲訂閱到第一個發射的時間間隔。

Timeout

對原始Observable的一個鏡像,如果過了一個指定的時長仍沒有發射數據,它會發一個錯誤通知

 Observable.create(new ObservableOnSubscribe<Integer>() {
            @Override
            public void subscribe(ObservableEmitter<Integer> observableEmitter) throws Exception {
                observableEmitter.onNext(1);
                Thread.sleep(1000);
                observableEmitter.onNext(2);
                Thread.sleep(1000);
                observableEmitter.onNext(3);
                Thread.sleep(3000);
                observableEmitter.onNext(4);
            }
        }).timeout(2000, TimeUnit.MILLISECONDS).subscribe(num -> System.out.println(num+"*"), throwable -> {System.out.println(throwable.getMessage());});

結果:

1*
2*
3*

The source did not signal an event for 2000 milliseconds and has been terminated.

timeout設置一個超時時間,當兩個發射時間的間隔大於設定時間時,就會拋出異常。

Timestamp

給Observable發射的數據項附加一個時間戳

Observable.create(new ObservableOnSubscribe<String>() {
            @Override
            public void subscribe(ObservableEmitter<String> observableEmitter) throws Exception {
                for (int i = 0; i < 3; i++){
                    try {
                        Thread.sleep(1000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    observableEmitter.onNext(i+"");
                }
                observableEmitter.onComplete();
            }
        }).timestamp(Schedulers.trampoline())
                .subscribe(new Consumer<Timed<String>>() {
                    @Override
                    public void accept(Timed<String> stringTimed) throws Throwable {
                        System.out.println(stringTimed.value() +"::" +stringTimed.time());
                    }
                });

結果:

0::1573968123248
1::1573968124248
2::1573968125257

與TimeInterval有點相似,不過TimeInterval讓發射數據帶有時間間隔。而Timestamp讓我們發射的數據帶有發射時的時間戳。

To

將Observable轉換爲另一個對象或數據結構

Observable.just(1, 2, 3, 4).toList().subscribe(new Consumer<List<Integer>>() {
            @Override
            public void accept(List<Integer> integers) throws Throwable {
                System.out.println(integers.get(3)+"++");
            }
        });

結果:

4++

toList就是把我們發射的數據弄成一個列表然後給到觀察者。

 

Observable.just(1, 2, 3, 4).toMap(new Function<Integer, String>() {
            @Override
            public String apply(Integer integer) throws Throwable {
                return integer+"";
            }
        }).subscribe(new Consumer<Map<String, Integer>>() {
            @Override
            public void accept(Map<String, Integer> map) throws Throwable {
                System.out.println(map.get("2")+"*");
            }
        });

結果:

2*

toMap就是把發射數據弄成一個map對象發射給訂閱者。而toMap裏面放的函數就是決定map的key。

Using

創建一個只在Observable生命週期內存在的一次性資源。這是官方說法,我只會按我自己理解說

Observable.using(new Supplier<Student>() {
            @Override
            public Student get() throws Throwable {
                Student student = new Student("aaa");
                return student;
            }
        }, new Function<Student, ObservableSource<String>>() {
            @Override
            public ObservableSource<String> apply(Student student) throws Throwable {
                return Observable.just(student.getName());
            }
        }, new Consumer<Student>() {
            @Override
            public void accept(Student student) throws Throwable {
                System.out.println(student.getName()+"++");

            }
        }).subscribe(str -> System.out.println(str+"*"));

結果:

aaa*
aaa++

using函數裏面的參數,一參爲返回這次要回收的資源,二參爲把這個資源轉換爲observable,然後由這個observable來訂閱我們的觀察者,三參爲數據處理完畢後,資源進入的函數,你就可以對這個資源進行回收或其他處理。

上面代碼,我們創了一個名爲aaa的學生對象,然後第二參數我們返回一個以學生名字的String的observable。先進入onNext訂閱的邏輯輸出了aaa*,然後再到第三參數函數的處理。

發佈了21 篇原創文章 · 獲贊 14 · 訪問量 2萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章