RxJava 學習筆記(八) --- Combining 結合操作

@(Rxjava學習筆記)

RxJava 學習筆記(八) — Combining 結合操作

1. StartWith —> 在數據序列的開頭插入一條指定的項

一個Observable在發射數據之前先發射一個指定的數據序列

            enter image description here

示例代碼:

Observable.just(10,20,30).startWith(2, 3, 4).subscribe(new Subscriber<Integer>() {
            @Override
            public void onCompleted() {
                System.out.println("Sequence complete.");
            }

            @Override
            public void onError(Throwable e) {
                System.err.println("Error: " + e.getMessage());
            }

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

輸出:

Next:2 
Next:3 
Next:4 
Next:10 
Next:20 
Next:30 
Sequence complete.

你也可以傳遞一個ObservablestartWith,它會將那個Observable的發射物插在原始Observable發射的數據序列之前,然後把這個當做自己的發射物集合。這可以看作是Concat的反轉。

            enter image description here

示例代碼:

Observable.just(1,2,3,4,5).startWith(Observable.just(9,8,5)).subscribe(new Action1<Integer>() {
            @Override
            public void call(Integer integer) {
                System.out.println(integer+"");
            }
        });

輸出:

9
8
5
1
2
3
4
5

2. Merge —> 將多個Observable合併爲一個

使用Merge操作符你可以將多個Observables的輸出合併,就好像它們是一個單個的Observable一樣。

Merge可能會讓合併的Observables發射的數據交錯(有一個類似的操作符Concat不會讓數據交錯,它會按順序一個接着一個發射多個Observables的發射物)。

正如圖例上展示的,任何一個原始ObservableonError通知會被立即傳遞給觀察者,而且會終止合併後的Observable

            enter image description here

示例代碼:

Observable<Integer> odds = Observable.just(1, 3, 5).subscribeOn(someScheduler);
Observable<Integer> evens = Observable.just(2, 4, 6);

Observable.merge(odds, evens)
          .subscribe(new Subscriber<Integer>() {
        @Override
        public void onNext(Integer item) {
            System.out.println("Next: " + item);
        }

        @Override
        public void onError(Throwable error) {
            System.err.println("Error: " + error.getMessage());
        }

        @Override
        public void onCompleted() {
            System.out.println("Sequence complete.");
        }
    });

輸出:

Next: 1
Next: 3
Next: 5
Next: 2
Next: 4
Next: 6
Sequence complete.

除了傳遞多個Observablemerge,你還可以傳遞一個Observable列表List,數組,甚至是一個發射Observable序列的Observablemerge將合併它們的輸出作爲單個Observable的輸出:

如果你傳遞一個發射Observables序列的Observable,你可以指定merge應該同時訂閱的Observable‘的最大數量。一旦達到訂閱數的限制,它將不再訂閱原始Observable發射的任何其它Observable,直到某個已經訂閱的Observable發射了onCompleted通知。

3. MergeDelayError —> 將多個Observable合併爲一個

它的行爲有一點不同,它會保留onError通知直到合併後的Observable所有的數據發射完成,在那時它纔會把onError傳遞給觀察者。

            enter image description here

示例代碼:

        //產生0,5,10數列,最後會產生一個錯誤
        Observable<Long> errorObservable = Observable.error(new Exception("this is end!"));
        Observable < Long > observable1 = Observable.timer(0, 1000, TimeUnit.MILLISECONDS)
                .map(new Func1<Long, Long>() {
                    @Override
                    public Long call(Long aLong) {
                        return aLong * 5;
                    }
                }).take(3).mergeWith(errorObservable.delay(3500, TimeUnit.MILLISECONDS));

        //產生0,10,20,30,40數列
        Observable<Long> observable2 = Observable.timer(500, 1000, TimeUnit.MILLISECONDS)
                .map(new Func1<Long, Long>() {
                    @Override
                    public Long call(Long aLong) {
                        return aLong * 10;
                    }
                }).take(5);

        Observable.mergeDelayError(observable1, observable2)
                .subscribe(new Subscriber<Long>() {
                    @Override
                    public void onCompleted() {
                        System.out.println("Sequence complete.");
                    }

                    @Override
                    public void onError(Throwable e) {
                        System.err.println("Error: " + e.getMessage());
                    }

                    @Override
                    public void onNext(Long aLong) {
                        System.out.println("Next:" + aLong);
                    }
                });

輸出:

Next:0 
Next:0 
Next:10 
Next:20 
Next:30 
Next:40 
Error: this is end!

4. Zip —> 使用一個函數組合多個Observable發射的數據集合,然後再發射這個結果

Zip
通過一個函數將多個Observables的發射物結合到一起,基於這個函數的結果爲每個結合體發射單個數據項。

            enter image description here

Zip操作符返回一個Obversable,它使用這個函數按順序結合兩個或多個Observables發射的數據項,然後它發射這個函數返回的結果。它按照嚴格的順序應用這個函數。它只發射與發射數據項最少的那個Observable一樣多的數據。

            enter image description here
zip的最後一個參數接受每個Observable發射的一項數據,返回被壓縮後的數據,它可以接受一到九個參數:一個Observable序列,或者一些發射ObservableObservables

Observable<Integer> observable1 = Observable.just(10,20,30);
        Observable<Integer> observable2 = Observable.just(4, 8, 12, 16);
        Observable.zip(observable1, observable2, new Func2<Integer, Integer, Integer>() {
            @Override
            public Integer call(Integer integer, Integer integer2) {
                return integer + integer2;
            }
        }).subscribe(new Subscriber<Integer>() {
            @Override
            public void onCompleted() {
                System.out.println("Sequence complete.");
            }

            @Override
            public void onError(Throwable e) {
                System.err.println("Error: " + e.getMessage());
            }

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

輸出:

Next:14 
Next:28 
Next:42 
Sequence complete.

ZipWith

            enter image description here

zipWith操作符總是接受兩個參數,第一個參數是一個Observable或者一個Iterable

zipzipWith默認不在任何特定的操作符上執行。

5. CombineLatest —> 當兩個Observables中的任何一個發射了一個數據時,通過一個指定的函數組合每個Observable發射的最新數據(一共兩個數據),然後發射這個函數的結果

            enter image description here

CombineLatest操作符行爲類似於zip,但是隻有當原始的Observable中的每一個都發射了一條數據時zip才發射數據。CombineLatest則在原始的Observable中任意一個發射了數據時發射一條數據。當原始Observables的任何一個發射了一條數據時,CombineLatest使用一個函數結合它們最近發射的數據,然後發射這個函數的返回值。

            enter image description here

示例代碼:

//產生0,5,10,15,20數列
        Observable<Long> observable1 = Observable.timer(0, 1000, TimeUnit.MILLISECONDS)
                .map(new Func1<Long, Long>() {
                    @Override
                    public Long call(Long aLong) {
                        return aLong * 5;
                    }
                }).take(5);

        //產生0,10,20,30,40數列
        Observable<Long> observable2 = Observable.timer(500, 1000, TimeUnit.MILLISECONDS)
                .map(new Func1<Long, Long>() {
                    @Override
                    public Long call(Long aLong) {
                        return aLong * 10;
                    }
                }).take(5);


        Observable.combineLatest(observable1, observable2, new Func2<Long, Long, Long>() {
            @Override
            public Long call(Long aLong, Long aLong2) {
                return aLong+aLong2;
            }
        }).subscribe(new Subscriber<Long>() {
            @Override
            public void onCompleted() {
                System.out.println("Sequence complete.");
            }

            @Override
            public void onError(Throwable e) {
                System.err.println("Error: " + e.getMessage());
            }

            @Override
            public void onNext(Long aLong) {
                System.out.println("Next: " + aLong);
            }
        });

輸出:

Next: 0 
Next: 5 
Next: 15 
Next: 20 
Next: 30 
Next: 35 
Next: 45 
Next: 50 
Next: 60 
Sequence complete.

6. Join —> 無論何時,如果一個Observable發射了一個數據項,只要在另一個Observable發射的數據項定義的時間窗口內,就將兩個Observable發射的數據合併發射

zip()merge()方法作用在發射數據的範疇內,在決定如何操作值之前有些場景我們需要考慮時間的。RxJavajoin()函數基於時間窗口將兩個Observables發射的數據結合在一起。+

            enter image description here

join方法的用法如下:
observableA.join(observableB,
observableA產生結果生命週期控制函數,
observableB產生結果生命週期控制函數,
observableA產生的結果與observableB產生的結果的合併規則)

示例代碼:

//產生0,5,10,15,20數列
        Observable<Long> observable1 = Observable.timer(0, 1000, TimeUnit.MILLISECONDS)
                .map(new Func1<Long, Long>() {
                    @Override
                    public Long call(Long aLong) {
                        return aLong * 5;
                    }
                }).take(5);

        //產生0,10,20,30,40數列
        Observable<Long> observable2 = Observable.timer(500, 1000, TimeUnit.MILLISECONDS)
                .map(new Func1<Long, Long>() {
                    @Override
                    public Long call(Long aLong) {
                        return aLong * 10;
                    }
                }).take(5);

        observable1.join(observable2, new Func1<Long, Observable<Long>>() {
            @Override
            public Observable<Long> call(Long aLong) {
                //使Observable延遲600毫秒執行
                return Observable.just(aLong).delay(600, TimeUnit.MILLISECONDS);
            }
        }, new Func1<Long, Observable<Long>>() {
            @Override
            public Observable<Long> call(Long aLong) {
                //使Observable延遲600毫秒執行
                return Observable.just(aLong).delay(600, TimeUnit.MILLISECONDS);
            }
        }, new Func2<Long, Long, Long>() {
            @Override
            public Long call(Long aLong, Long aLong2) {
                return aLong + aLong2;
            }
        }).subscribe(new Subscriber<Long>() {
            @Override
            public void onCompleted() {
                System.out.println("Sequence complete.");
            }

            @Override
            public void onError(Throwable e) {
                System.err.println("Error: " + e.getMessage());
            }

            @Override
            public void onNext(Long aLong) {
                System.out.println("Next: " + aLong);
            }
        });

輸出:

Next: 0 
Next: 5 
Next: 15 
Next: 20 
Next: 30 
Next: 35 
Next: 45 
Next: 50 
Next: 60 
Sequence complete.

7. GroupJoin —> groupJoin操作符非常類似於join操作符,區別在於join操作符中第四個參數的傳入函數不一致

            enter image description here

示例代碼:

        //產生0,5,10,15,20數列
        Observable<Long> observable1 = Observable.timer(0, 1000, TimeUnit.MILLISECONDS)
                .map(new Func1<Long, Long>() {
                    @Override
                    public Long call(Long aLong) {
                        return aLong * 5;
                    }
                }).take(5);

        //產生0,10,20,30,40數列
        Observable<Long> observable2 = Observable.timer(500, 1000, TimeUnit.MILLISECONDS)
                .map(new Func1<Long, Long>() {
                    @Override
                    public Long call(Long aLong) {
                        return aLong * 10;
                    }
                }).take(5);

        observable1.groupJoin(observable2, new Func1<Long, Observable<Long>>() {
            @Override
            public Observable<Long> call(Long aLong) {
                return Observable.just(aLong).delay(1600, TimeUnit.MILLISECONDS);
            }
        }, new Func1<Long, Observable<Long>>() {
            @Override
            public Observable<Long> call(Long aLong) {
                return Observable.just(aLong).delay(600, TimeUnit.MILLISECONDS);
            }
        }, new Func2<Long, Observable<Long>, Observable<Long>>() {
            @Override
            public Observable<Long> call(Long aLong, Observable<Long> observable) {
                return observable.map(new Func1<Long, Long>() {
                    @Override
                    public Long call(Long aLong2) {
                        return aLong + aLong2;
                    }
                });
            }
        }).subscribe(new Subscriber<Observable<Long>>() {
            @Override
            public void onCompleted() {
                System.out.println("Sequence complete.");
            }

            @Override
            public void onError(Throwable e) {
                System.err.println("Error: " + e.getMessage());
            }

            @Override
            public void onNext(Observable<Long> observable) {
                observable.subscribe(new Subscriber<Long>() {
                    @Override
                    public void onCompleted() {

                    }

                    @Override
                    public void onError(Throwable e) {

                    }

                    @Override
                    public void onNext(Long aLong) {
                        System.out.println("Next: " + aLong);
                    }
                });
            }
        });

輸出:

Next: 5
Next: 15
Next: 10
Next: 20
Next: 25
Next: 30
Next: 35
Next: 45
Next: 40
Next: 50
Next: 60
Next: 55
Sequence complete.

8. SwitchOnNext —> 將一個發射Observables的Observable轉換成另一個Observable,後者發射這些Observables最近發射的數據

            enter image description here

switchOnNext操作符是把一組Observable轉換成一個Observable,轉換規則爲:對於這組Observable中的每一個Observable所產生的結果,如果在同一個時間內存在兩個或多個Observable提交的結果,只取最後一個Observable提交的結果給訂閱者

示例代碼:

        //每隔500毫秒產生一個observable
        Observable<Observable<Long>> observable = Observable.timer(0, 500, TimeUnit.MILLISECONDS).map(new Func1<Long, Observable<Long>>() {
            @Override
            public Observable<Long> call(Long aLong) {
                //每隔200毫秒產生一組數據(0,10,20,30,40)
                return Observable.timer(0, 200, TimeUnit.MILLISECONDS).map(new Func1<Long, Long>() {
                    @Override
                    public Long call(Long aLong) {
                        return aLong * 10;
                    }
                }).take(5);
            }
        }).take(2);

        Observable.switchOnNext(observable).subscribe(new Subscriber<Long>() {
            @Override
            public void onCompleted() {
                System.out.println("Sequence complete.");
            }

            @Override
            public void onError(Throwable e) {
                System.err.println("Error: " + e.getMessage());
            }

            @Override
            public void onNext(Long aLong) {
                System.out.println("Next:" + aLong);
            }
        });

輸出:

Next:0 
Next:10 
Next:20 
Next:0 
Next:10 
Next:20 
Next:30 
Next:40 
Sequence complete.
發佈了34 篇原創文章 · 獲贊 8 · 訪問量 3萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章