RxJava操作符的一些記錄

介紹

在項目中使用RxJava實現響應式編碼有一段時間,RxJava的強大,簡單的使用已經能夠滿足普通的開發需求,爲了記錄和加深自己的對RxJava的理解,寫這篇博客記錄一些自己對RxJava的使用和理解。

前期說明

下文用代碼說明一些操作符的功能和使用。
首先提供基本的可觀察對象,以下是基本的對象,後文中會根據需要進行修改。爲了簡化代碼使用lamdba表達式。

static Observable<String> sampleObserbableString(){
        return Observable.create(subscriber -> {
            for (int i = 0; i < 2; i++) {
                subscriber.onNext("start "+ i);
                Logger.d("start "+ i);
            } 
            subscriber.onCompleted();
        });
    }

Map

代碼:先訪問得到可觀察的序列然後map轉換,給每個值加上“map”,打印結果。

 sampleObservableString()
                .map(new Func1<String, String>() {
                    @Override
                    public String call(String s) {
                        return s+" map";
                    }
                })
                .subscribe(new Subscriber<String>() {
                    @Override
                    public void onCompleted() {
                        Logger.d();
                    }

                    @Override
                    public void onError(Throwable e) {
                        Logger.d(e.toString());
                    }

                    @Override
                    public void onNext(String s) {
                        Logger.d(s);
                    }
                });

可以看到,原來發射序列的onNext方法發送的值被map加工,然後觀察得到被map加工後的結果。

Log打印
04-20 14:48:21.835 [RxAndroidFragment:onNext:121]: start 0 map
04-20 14:48:21.836 [RxAndroidFragment:lambdasampleObservableString 1:130]: start 0
04-20 14:48:21.836 [RxAndroidFragment:onNext:121]: start 1 map
04-20 14:48:21.837 [RxAndroidFragment:lambdasampleObservableString 1:130]: start 1
04-20 14:48:21.839 [RxAndroidFragment:onCompleted:111]:

官方說明:
map說明圖

map:是對每個元素進行轉換。

flatMap

代碼:訂閱打印方式和map的代碼一樣,只修改調用了flatmap方法

   sampleObservableString()
                .flatMap(s -> sampleObservableString2())
                .subscribe(打印結果)

可以看到,得到2*2=4次onNext打印結果。因爲每次原始數據的onNext都激發了flatmap中新數據源發射數據。這裏考慮有可能我兩個observable都是String類型對結果的影響,我改變代碼中的sampleObservableInteger2發射int包裝類,並訂閱。結果一樣也是4次打印結果。

04-20 15:02:28.727 [RxAndroidFragment:onNext:116]: from 0
04-20 15:02:28.727 [RxAndroidFragment:lambdasampleObservableString2 3:135]: from 0
04-20 15:02:28.728 [RxAndroidFragment:onNext:116]: from 1
04-20 15:02:28.728 [RxAndroidFragment:lambdasampleObservableString2 3:135]: from 1
04-20 15:02:28.729 [RxAndroidFragment:lambdasampleObservableString 2:125]: start 0
04-20 15:02:28.730 [RxAndroidFragment:onNext:116]: from 0
04-20 15:02:28.730 [RxAndroidFragment:lambdasampleObservableString2 3:135]: from 0
04-20 15:02:28.731 [RxAndroidFragment:onNext:116]: from 1
04-20 15:02:28.731 [RxAndroidFragment:lambdasampleObservableString2 3:135]: from 1
04-20 15:02:28.732 [RxAndroidFragment:lambdasampleObservableString 2:125]: start 1
04-20 15:02:28.733 [RxAndroidFragment:onCompleted:106]:

官方說明:
flatmap說明圖

flatmap:提供一種鋪平序列的方式,然後合併這些Observables發射的數據,最後將合併後的結果作爲最終的Observable。

借用這篇博客的說明:
flatMap() 的原理是這樣的:
1. 使用傳入的事件對象創建一個 Observable 對象;2. 並不發送這個 Observable, 而是將它激活,於是它開始發送事件;3. 每一個創建出來的 Observable 發送的事件,都被匯入同一個 Observable ,而這個 Observable 負責將這些事件統一交給 Subscriber 的回調方法。這三個步驟,把事件拆成了兩級,通過一組新創建的 Observable 將初始的對象『鋪平』之後通過統一路徑分發了下去。而這個『鋪平』就是 flatMap() 所謂的 flat。

ConcatMap/FlatMapIterable

concatMap():函數解決了flatMap()的交叉問題(上圖能看到flatmap有交叉情況)提供了一種能夠把發射的值連續在一起的鋪平函數,而不是合併它們。由於代碼模擬比較簡單就不說用代碼說明。主要就是順序有了保證。
flatMapInterable():和flatMap()很像。僅有的本質不同是,它不是原始數據項和生成的Observables,而是將源數據兩兩結成對並生成Iterable。

debounce

debounce是過濾掉由Observable發射的速率過快的數據,這就需要修改我的發射源。
代碼如下:在發射3個元素的中間元素1時,休眠200毫秒,設置一個100毫秒間隔的debounce過濾

 static Observable<String> sampleObservableString() {
        return Observable.create(subscriber -> {
            for (int i = 0; i < 3; i++) {
                if (i==1) {
                    try {
                        Thread.sleep(200);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
                subscriber.onNext("start " + i);
                Logger.d("start " + i);
            }
            subscriber.onCompleted();
        });
    }
 sampleObservableString()
                .debounce(100, TimeUnit.MILLISECONDS)
                .subscribe(打印結果)

打印結果:得到了2次結果,中間那次被過濾掉了。因爲後兩次間隔太近。

04-20 16:09:59.817 [RxAndroidFragment:lambdasampleObservableString 1:150]: start 0
04-20 16:09:59.916 20468-20524/com.demo.liyi.HttpDemo D/mDemo: [RxAndroidFragment:onNext:134]: start 0
04-20 16:10:01.818 [RxAndroidFragment:lambdasampleObservableString 1:150]: start 1
04-20 16:10:01.819 [RxAndroidFragment:lambdasampleObservableString 1:150]: start 2
04-20 16:10:01.819 [RxAndroidFragment:onNext:134]: start 2
04-20 16:10:01.820 [RxAndroidFragment:onCompleted:124]:
圖片說明:圖片可以更好的說明
結果的圖片說明

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章