RxJava——組合操作符

前言
在RxJava中, 同時處理多個Observables是很常見的一種操作。下面我們簡單分析下幾個組合類的操作符。

  1. Merge
    在異步的世界經常會創建這樣的場景,我們有多個來源但是只想有一個結果:多輸入,單輸出。RxJava的merge()方法將幫助你把兩個甚至更多的Observables合并到他們發射的數據里。下圖給出了把兩個序列合并在一個最終發射的Observable。
merge.png
/**
     * Merge 解釋:將2-9個Observables合并到一個Observable中進行發射,合并后的數據可能會是交錯(無序)的(如果想要沒有交錯,
     * 可以使用concat操作符) merge還可以傳遞一個Observable列表List,數組
     * 甚至是一個發射Observable序列的Observable,merge將合并它們的輸出作為單個Observable的輸出
     */
 Observable<String> letterObservable = Observable.just("A", "B", "C", "D");
        Observable<Integer> numberObservable = Observable.just(1, 2, 3, 4);

        Observable.merge(letterObservable, numberObservable)
                .subscribe(new Action1<Serializable>() {
                    @Override
                    public void call(Serializable serializable) {
                        System.out.println("value =" + serializable);
                    }
                });

    }

value =A
value =B
value =C
value =D
value =1
value =2
value =3
value =4
例如:我們加載Recyclerview數據時,我們從多個地方獲取,但是只有一個輸出,可以用merge處理

2.Zip
我們在處理多源時可能會帶來這樣一種場景:多從個Observables接收數據,處理它們,然后將它們合并成一個新的可觀測序列來使用。RxJava有一個特殊的方法可以完成:zip()合并兩個或者多個Observables發射出的數據項,根據指定的函數Func*變換它們,并發射一個新值。下圖展示了zip()方法如何處理發射的“numbers”和“letters”然后將它們合并一個新的數據項:

zip.png

如圖可以看到,zip操作符并不是像merge操作符那樣只合并了數據,重要的是發生了質的變化。

Observable letterObservable = Observable.just("A", "B", "C", "D");
        Observable numberObservable = Observable.just(1, 2, 3, 4, 5);

        Observable.zip(letterObservable, numberObservable, new Func2<String, Integer, String>() {
            @Override
            public String call(String o, Integer o2) {
                return o + o2;
            }
        }).subscribe(new Action1<String>() {
            @Override
            public void call(String o) {
                System.out.println("value :"+o);
            }
        });

value :A1
value :B2
value :C3
value :D4
注意: 
zip操作符合并后的Observable數據類型可以發生改變。

3.combineLatest
RxJava的combineLatest()函數有點像zip()函數的特殊形式。正如我們已經學習的,zip()作用于最近未打包的兩個Observables。相反,combineLatest()作用于最近發射的數據項:如果Observable1發射了A并且Observable2發射了B和C,combineLatest()將會分組處理AB和AC,如下圖所示:

combineLatest.png
 Observable letterObservable = Observable.just("a", "b", "c");
        Observable numberObservable = Observable.just(1, 2, 3);
        Observable.combineLatest(letterObservable, numberObservable, new Func2<String, Integer, String>() {
            @Override
            public String call(String t1, Integer t2) {
                System.out.println("combine  t1 = " + t1 + " | t2 = " + t2);// t1的值一開始就是letterObservable中的最后一個值
                return t1 + t2;
            }
        }).subscribe(new Action1() {
            @Override
            public void call(Object o) {
                System.out.println("value = " + o);
            }
        });

combine  t1 = c | t2 = 1
value = c1
combine  t1 = c | t2 = 2
value = c2
combine  t1 = c | t2 = 3
value = c3

  1. Join
    前面兩個方法,zip()和merge()方法作用在發射數據的范疇內,在決定如何操作值之前有些場景我們需要考慮時間的。RxJava的join()函數基于時間窗口將兩個Observables發射的數據結合在一起。
join.png

為了正確的理解上一張圖,我們解釋下join()需要的參數:

  第二個Observable和源Observable結合。
   Func1參數:在指定的由時間窗口定義時間間隔內,源Observable發射的數據和從第二個Observable發射的數據相互配合返回的Observable。
Func1參數:在指定的由時間窗口定義時間間隔內,第二個Observable發射的數據和從源Observable發射的數據相互配合返回的Observable。
Func2參數:定義已發射的數據如何與新發射的數據項相結合。
 Observable<Integer> observableA=Observable.range(1,5);

        List<Integer> data= Arrays.asList(6,7,8,9,10);
        Observable<Integer> observableB=Observable.from(data);

        observableA.join(observableB, new Func1<Integer, Observable<Integer>>() {
            @Override
            public Observable<Integer> call(Integer integer) {
                return Observable.just(integer).delay(1, TimeUnit.SECONDS);
            }
        }, new Func1<Integer, Observable<Integer>>() {
            @Override
            public Observable<Integer> call(Integer integer) {
                return Observable.just(integer);
            }
        },new Func2<Integer, Integer, Integer>() {
            @Override
            public Integer call(Integer value1, Integer value2) {
                System.out.println("left: " + value1 + "  right:" + value2);
                return value1 + value2;
            }
        }).subscribe(new Observer<Integer>() {
            @Override
            public void onCompleted() {

            }

            @Override
            public void onError(Throwable e) {

            }

            @Override
            public void onNext(Integer integer) {
                System.out.println("onNext value = " + integer);
            }
        });

一句話概括:在observableA的生命周期內:observableB輸出的數據項與observableA輸出的數據項每個合并
left: 1  right:6
onNext value = 7
left: 2  right:6
onNext value = 8
left: 3  right:6
onNext value = 9
left: 4  right:6
onNext value = 10
left: 5  right:6
onNext value = 11
left: 1  right:7
onNext value = 8
left: 2  right:7
onNext value = 9
left: 3  right:7
onNext value = 10
left: 4  right:7
onNext value = 11
left: 5  right:7
onNext value = 12。。。。。。

5.StartWith
在源Observable輸出之前插入指定數據項

startWith.png
Observable.just(7,8,9).startWith(11,12).subscribe(new Observer<Integer>() {
            @Override
            public void onCompleted() {

            }

            @Override
            public void onError(Throwable e) {

            }

            @Override
            public void onNext(Integer integer) {
                System.out.println("onNext t = " + integer);
            }
        });

onNext t = 11
onNext t = 12
onNext t = 7
onNext t = 8
onNext t = 9

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容