RxJava操作符系列傳送門
RxJava操作符源碼
RxJava操作符系列一
RxJava操作符系列二
RxJava操作符系列三
前言
在上一篇文章我們主要介紹的是RxJava的一些過濾操作符,若將過濾操作和轉換操作一起使用,能處理複雜的的業務邏輯,在文章中所舉的例子都是都是很簡單的邏輯,簡單的讓人感覺這樣寫沒必要,當然這這是爲了便於理解操作符的含義,只有理解了這些基礎上我們才能做更復雜的操作。相信通過學習,能感悟出RxJava的強大。讓我們繼續開啓學習之旅吧。
Merge
該操作符可以將多個Observables的輸出合併,就好像它們是一個單個的Observable一樣,他可能讓我們讓合併的Observables發射的數據交錯(順序發生變化),在此過程中任何一個原始Observable的onError通知都會被立即傳遞給觀察者,而且會終止合併後的Observable。
Observable observable=Observable.just(1,2);
Observable observable1=Observable.just(6,7);
Observable.merge(observable, observable1)
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Subscriber<Integer>() {
@Override
public void onCompleted() {
Log.e(TAG, "onCompleted: ");
}
@Override
public void onError(Throwable e) {
Log.e(TAG, "onError: "+e.toString() );
}
@Override
public void onNext(Integer s) {
Log.e(TAG, "onNext: "+s);
}
});
輸出日誌信息
onNext: 1
onNext: 2
onNext: 6
onNext: 7
onCompleted:
如果我們此時在創建一個Obserable如下
Observable observable2 = Observable.create(new Observable.OnSubscribe<Integer>() {
@Override
public void call(Subscriber<? super Integer> subscriber) {
try {
Thread.sleep(500);
subscriber.onNext(200);
subscriber.onCompleted();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}).subscribeOn(Schedulers.newThread());
然後將merge(observable, observable1)更改爲merge(observable2,observable, observable1)
再次執行,發現雖然observable2是第一個參數,但是輸出卻是在最後一個輸出。
MergeDelayError
對於merge操作符的任何一個的Observable發射了onError通知終止了,merge操作符生成的Observable也會立即以onError通知終止。如果你想讓它繼續發射數據,在最後才報告錯誤,可以使用mergeDelayError。我們先使用merge將observable2的創建代碼更改下面代碼,依然執行merge(observable2,observable, observable1)。
Observable observable2 = Observable.create(new Observable.OnSubscribe<Integer>() {
@Override
public void call(Subscriber<? super Integer> subscriber) {
try {
subscriber.onNext(100);
subscriber.onError(new Throwable("error"));
subscriber.onCompleted();
} catch (InterruptedException e) {
e.printStackTrace();
subscriber.onError(new Throwable("error11"));
}
}
}).subscribeOn(Schedulers.newThread()).observeOn(AndroidSchedulers.mainThread());
輸出日誌信息
onError: java.lang.Throwable: error
由於observable2 的異常,導致observable和 observable1被中斷。
那麼如果在這種情況下依然發送數據該怎麼辦呢,MergeDelayError就可以達到這樣的效果,看如下實現代碼。最後提醒下MergeDelayError的使用有個坑,就是subscribeOn和observeOn的調用問題,如果先mergeDelayError之後再用subscribeOn和observeOn指定調度器發現該操作符並不起作用。需要在單獨創建Observable時使用,如下示例代碼
Observable observable = Observable.create(new Observable.OnSubscribe<Integer>() {
@Override
public void call(Subscriber<? super Integer> subscriber) {
try {
subscriber.onNext(100);
subscriber.onError(new Throwable("error"));
subscriber.onCompleted();
} catch (InterruptedException e) {
e.printStackTrace();
subscriber.onError(new Throwable("error11"));
}
}
}).subscribeOn(Schedulers.newThread()).observeOn(AndroidSchedulers.mainThread());
Observable observable3=Observable.just(6,7,8,9).subscribeOn(Schedulers.newThread()).observeOn(AndroidSchedulers.mainThread());
Observable.merge(observable,observable1)
.subscribe(new Subscriber<Integer>() {
@Override
public void onCompleted() {
Log.e(TAG, "onCompleted: ");
}
@Override
public void onError(Throwable e) {
Log.e(TAG, "onError: "+e.toString() );
}
@Override
public void onNext(Integer s) {
Log.e(TAG, "onNext: "+s);
}
});
輸出日誌信息
onNext: 6
onNext: 7
onNext: 8
onNext: 9
onError: java.lang.Throwable: error
Concat
該操作符和merge操作符相似,不同之處就是該操作符按順序一個接着一個發射多個Observables的發射物。保證順序性。
Observable observableA = Observable.create(new Observable.OnSubscribe<Integer>() {
@Override
public void call(Subscriber<? super Integer> subscriber) {
try {
subscriber.onNext(100);
Thread.sleep(500);
subscriber.onNext(200);
subscriber.onCompleted();
} catch (InterruptedException e) {
e.printStackTrace();
subscriber.onError(new Throwable("error11"));
}
}
}).subscribeOn(Schedulers.newThread()).observeOn(AndroidSchedulers.mainThread());
Observable<Integer> observableB = Observable.range(7, 2);
Observable.concat(observableA, observableB).subscribe(new Subscriber<Integer>() {
@Override
public void onCompleted() {
Log.e(TAG, "onCompleted: concat");
}
@Override
public void onError(Throwable e) {
Log.e(TAG, "onError: concat");
}
@Override
public void onNext(Integer integer) {
Log.e(TAG, "onNext: concat" + integer);
}
});
輸出日誌信息
onNext: concat100
onNext: concat200
onNext: concat7
onNext: concat8
onCompleted: concat
這樣就保證了順序性,如果用merge的話,100和200應該在7和8後輸出。
Zip
該操作符返回一個Obversable,它使用這個函數按順序結合兩個或多個Observables發射的數據項,然後它發射這個函數返回的結果。它按照嚴格的順序應用這個函數。它只發射與發射數據項最少的那個Observable一樣多的數據,假如兩個Observable數據分佈爲4項,5項,則最終合併是4項。如下示例代碼
List<String> names = new ArrayList<>();
List<Integer> ages = new ArrayList<>();
for (int i = 0; i < 5; i++) {
names.add("張三" + i);
ages.add(20 + i);
}
ages.add(15);
Observable observable1 = Observable.from(names).subscribeOn(Schedulers.io());
Observable observable2 = Observable.from(ages).subscribeOn(Schedulers.io());
//Func2第三個參數是返回值類型
Observable.zip(observable1, observable2, new Func2<String, Integer, String>() {
@Override
public String call(String name, Integer age) {
return name + ": " + age;
}
}).observeOn(AndroidSchedulers.mainThread()).subscribe(new Subscriber<String>() {
@Override
public void onCompleted() {
Log.e(TAG, "onCompleted: ");
}
@Override
public void onError(Throwable e) {
Log.e(TAG, "onError: ");
}
@Override
public void onNext(String o) {
Log.e(TAG, "onNext: " + o);
}
});
輸出日誌信息
onNext: 張三0: 20
onNext: 張三1: 21
onNext: 張三2: 22
onNext: 張三3: 23
onNext: 張三4: 24
onCompleted:
StartWith
該操作符作用是在一個Observable在發射數據之前先發射一個指定的數據序列。如下
Observable.range(1,3).startWith(11,12).subscribe(new Subscriber<Integer>() {
@Override
public void onCompleted() {
Log.e(TAG, "onCompleted: " );
}
@Override
public void onError(Throwable e) {
Log.e(TAG, "onError: ");
}
@Override
public void onNext(Integer integer) {
Log.e(TAG, "onNext: "+integer );
}
});
輸出日誌信息
onNext: 11
onNext: 12
onNext: 1
onNext: 2
onNext: 3
onCompleted:
CombineLatest
操作符行爲類似於zip,但是隻有當原始的Observable中的每一個都發射了一條數據時zip才發射數據。CombineLatest則在原始的Observable中任意一個發射了數據時發射一條數據。當原始Observables的任何一個發射了一條數據時,CombineLatest使用一個函數結合它們最近發射的數據,然後發射這個函數的返回值。通過上面的圖應該更容易理解。
示例代碼
Observable<Integer> observableA = Observable.range(1, 4);
Observable<Integer> observableB = Observable.range(10, 5);
Observable.combineLatest(observableA, observableB, new Func2<Integer, Integer, String>() {
@Override
public String call(Integer integer, Integer integer2) {
Log.e(TAG, "call: combineLatest");
return "observableA:" + integer + " observableB:" + integer2;
}
}).subscribe(new Action1<String>() {
@Override
public void call(String s) {
Log.e(TAG, "call: combineLatest" + s);
}
});
輸出日誌信息
call: combineLatest
call: combineLatestobservableA:4 observableB:10
call: combineLatest
call: combineLatestobservableA:4 observableB:11
call: combineLatest
call: combineLatestobservableA:4 observableB:12
call: combineLatest
call: combineLatestobservableA:4 observableB:13
call: combineLatest
call: combineLatestobservableA:4 observableB:14
Join
該操作符只要在另一個Observable發射的數據定義的時間窗口內,這個Observable發射了一條數據,就結合兩個Observable發射的數據.例如A作爲基礎窗口,當A發射了數據1,2,3,4,5時,B發射了一個數據a.則此時合併數據(1,a),(2,a),(3,a),(4,a),(5,a),此時將窗口清楚並重新打開一個窗口循環此種操作直到數據輸出完畢。
示例代碼
Observable<Integer> observableA = Observable.range(1, 2).subscribeOn(Schedulers.newThread());
Observable<Integer> observableB = Observable.range(7, 3).subscribeOn(Schedulers.newThread());
observableA.join(observableB, new Func1<Integer, Observable<Integer>>() {
@Override
public Observable<Integer> call(Integer integer) {
Log.e(TAG, "call: A" + integer +" "+ Thread.currentThread().getName());
return Observable.just(integer).delay(1,TimeUnit.SECONDS);
}
}, new Func1<Integer, Observable<Integer>>() {
@Override
public Observable<Integer> call(Integer integer) {
Log.e(TAG, "call: B" + integer +" "+ Thread.currentThread().getName());
return Observable.just(integer).delay(1,TimeUnit.SECONDS);
}
}, new Func2<Integer, Integer, Integer>() {
@Override
public Integer call(Integer integer, Integer integer2) {
Log.e(TAG, "call:AjoinB A: " + integer + " B:" + integer2 + Thread.currentThread().getName());
return integer+integer2;
}
}).observeOn(AndroidSchedulers.mainThread())
.subscribe(new Subscriber<Integer>() {
@Override
public void onCompleted() {
Log.e(TAG, "onCompleted: ");
}
@Override
public void onError(Throwable e) {
Log.e(TAG, "onError: "+e.toString());
}
@Override
public void onNext(Integer integer) {
Log.e(TAG, "onNext: "+integer);
}
});
輸出日誌信息
call: A1 RxNewThreadScheduler-4
call: A2 RxNewThreadScheduler-4
call: B7 RxNewThreadScheduler-5
call:AjoinB A: 1 B:7RxNewThreadScheduler-5
call:AjoinB A: 2 B:7RxNewThreadScheduler-5
call: B8 RxNewThreadScheduler-5
call:AjoinB A: 1 B:8RxNewThreadScheduler-5
call:AjoinB A: 2 B:8RxNewThreadScheduler-5
call: B9 RxNewThreadScheduler-5
onNext: 8
onNext: 9
onNext: 9
call:AjoinB A: 1 B:9RxNewThreadScheduler-5
call:AjoinB A: 2 B:9RxNewThreadScheduler-5
onNext: 10
onNext: 10
onNext: 11
onCompleted:
switchOnNext
該操作符將一個發射多個Observables的Observable轉換成另一個單獨的Observable,後者發射那些Observables最近發射的數據項。當有新的Observable開始訂閱時,會取消之前的訂閱,並將數據丟棄。如下示例
Observable<Observable<Long>> observable = Observable.interval(0, 500, TimeUnit.MILLISECONDS).map(new Func1<Long, Observable<Long>>() {
@Override
public Observable<Long> call(Long aLong) {
//每隔200毫秒產生一組數據(0,10,20,30,40)
Log.e(TAG, "call1: "+aLong);
return Observable.interval(0, 200, TimeUnit.MILLISECONDS).map(new Func1<Long, Long>() {
@Override
public Long call(Long aLong) {
Log.e(TAG, "call2: "+aLong );
return aLong * 10;
}
}).take(5);
}
}).take(2);
Observable.switchOnNext(observable).subscribe(new Subscriber<Long>() {
@Override
public void onCompleted() {
Log.e(TAG, "onCompleted: SwitchOnNext" );
}
@Override
public void onError(Throwable e) {
Log.e(TAG, "onError: SwitchOnNext");
}
@Override
public void onNext(Long aLong) {
Log.e(TAG, "onNext: SwitchOnNext "+aLong);
}
});
輸出日誌信息
call1: 0
call2: 0
onNext: SwitchOnNext 0
call2: 1
onNext: SwitchOnNext 10
call2: 2
onNext: SwitchOnNext 20
call1: 1
call2: 0
onNext: SwitchOnNext 0
call2: 1
onNext: SwitchOnNext 10
call2: 2
onNext: SwitchOnNext 20
call2: 3
onNext: SwitchOnNext 30
call2: 4
onNext: SwitchOnNext 40
onCompleted: SwitchOnNext
今天的這篇文章就到此結束,歡迎大家閱讀,若發現文中有錯誤的地方歡迎留言提出,感謝。