@(Rxjava學習筆記)
RxJava 學習筆記(八) — Combining 結合操作
- RxJava 學習筆記八 Combining 結合操作
- StartWith 在數據序列的開頭插入一條指定的項
- Merge 將多個Observable合併爲一個
- MergeDelayError 將多個Observable合併爲一個
- Zip 使用一個函數組合多個Observable發射的數據集合然後再發射這個結果
- CombineLatest 當兩個Observables中的任何一個發射了一個數據時通過一個指定的函數組合每個Observable發射的最新數據一共兩個數據然後發射這個函數的結果
- Join 無論何時如果一個Observable發射了一個數據項只要在另一個Observable發射的數據項定義的時間窗口內就將兩個Observable發射的數據合併發射
- GroupJoin groupJoin操作符非常類似於join操作符區別在於join操作符中第四個參數的傳入函數不一致
- SwitchOnNext 將一個發射Observables的Observable轉換成另一個Observable後者發射這些Observables最近發射的數據
1. StartWith
—> 在數據序列的開頭插入一條指定的項
一個Observable
在發射數據之前先發射一個指定的數據序列
示例代碼:
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.
- Javadoc:startWith(T) (最多接受九個參數)
- Javadoc:startWith(Iterable)
你也可以傳遞一個Observable
給startWith
,它會將那個Observable
的發射物插在原始Observable
發射的數據序列之前,然後把這個當做自己的發射物集合。這可以看作是Concat
的反轉。
示例代碼:
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
- Javadoc:startWith(Observable)
2. Merge
—> 將多個Observable合併爲一個
使用Merge
操作符你可以將多個Observables
的輸出合併,就好像它們是一個單個的Observable
一樣。
Merge
可能會讓合併的Observables
發射的數據交錯(有一個類似的操作符Concat
不會讓數據交錯,它會按順序一個接着一個發射多個Observables
的發射物)。
正如圖例上展示的,任何一個原始Observable
的onError
通知會被立即傳遞給觀察者,而且會終止合併後的Observable
。
示例代碼:
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.
除了傳遞多個Observable
給merge
,你還可以傳遞一個Observable
列表List
,數組,甚至是一個發射Observable
序列的Observable
,merge
將合併它們的輸出作爲單個Observable
的輸出:
如果你傳遞一個發射Observables
序列的Observable
,你可以指定merge
應該同時訂閱的Observable
‘的最大數量。一旦達到訂閱數的限制,它將不再訂閱原始Observable
發射的任何其它Observable
,直到某個已經訂閱的Observable
發射了onCompleted
通知。
- Javadoc:merge(Observable,Observable) (接受二到九個Observable)
- Javadoc:merge(Observable[])
- Javadoc:merge(Iterable)
- Javadoc:merge(Iterable,int)
3. MergeDelayError
—> 將多個Observable合併爲一個
它的行爲有一點不同,它會保留onError
通知直到合併後的Observable
所有的數據發射完成,在那時它纔會把onError
傳遞給觀察者。
示例代碼:
//產生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!
- Javadoc:mergeDelayError(Observable)
- Javadoc:mergeDelayError(Observable,Observable)
4. Zip
—> 使用一個函數組合多個Observable發射的數據集合,然後再發射這個結果
Zip
通過一個函數將多個Observables
的發射物結合到一起,基於這個函數的結果爲每個結合體發射單個數據項。
Zip
操作符返回一個Obversable
,它使用這個函數按順序結合兩個或多個Observables
發射的數據項,然後它發射這個函數返回的結果。它按照嚴格的順序應用這個函數。它只發射與發射數據項最少的那個Observable
一樣多的數據。
zip
的最後一個參數接受每個Observable
發射的一項數據,返回被壓縮後的數據,它可以接受一到九個參數:一個Observable
序列,或者一些發射Observable
的Observables
。
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.
- Javadoc:zip(Iterable,FuncN)
- Javadoc:zip(Observable,FuncN)
- Javadoc:zip(Observable,Observable,Func2) (最多可以有九個Observables參數)
ZipWith
zipWith
操作符總是接受兩個參數,第一個參數是一個Observable
或者一個Iterable
。
zip
和zipWith
默認不在任何特定的操作符上執行。
- Javadoc:zipWith(Observable,Func2)
- Javadoc:zipWith(Iterable,Func2)
5. CombineLatest
—> 當兩個Observables中的任何一個發射了一個數據時,通過一個指定的函數組合每個Observable發射的最新數據(一共兩個數據),然後發射這個函數的結果
CombineLatest
操作符行爲類似於zip
,但是隻有當原始的Observable
中的每一個都發射了一條數據時zip
才發射數據。CombineLatest
則在原始的Observable
中任意一個發射了數據時發射一條數據。當原始Observables
的任何一個發射了一條數據時,CombineLatest
使用一個函數結合它們最近發射的數據,然後發射這個函數的返回值。
示例代碼:
//產生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.
- Javadoc:combineLatest(List,FuncN)
- Javadoc:combineLatest(Observable,Observable,Func2)
6. Join
—> 無論何時,如果一個Observable發射了一個數據項,只要在另一個Observable發射的數據項定義的時間窗口內,就將兩個Observable發射的數據合併發射
zip()
和merge()
方法作用在發射數據的範疇內,在決定如何操作值之前有些場景我們需要考慮時間的。RxJava
的join()
函數基於時間窗口將兩個Observables
發射的數據結合在一起。+
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操作符中第四個參數的傳入函數不一致
示例代碼:
//產生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最近發射的數據
switchOnNex
t操作符是把一組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.
- Javadoc:switchOnNext(Observable)