前言
本篇介绍结合类操作符(基于Rxjava2),包括:concat
、concatArray
、concatDelayError
、merge
、mergeArray
、mergeDelayError
、zip
、zipWith
、combineLatest
、combineLatestDelayError
、join
、joinGroup
、startWith
、startWithArray
、switchOnNext
1,concat()
- 描述:组合最多4个被观察者一起发送数据,合并后按发送顺序执行
- 示例:
Observable.concat(
Observable.just(1, 2),
Observable.just(3, 4),
Observable.just(5, 6))
.subscribe(new Consumer<Integer>() {
@Override
public void accept(Integer integer) throws Exception {
Log.i(TAG,"accept:"+integer);
}
});
}
输出:
2,concatArray()
描述:组合多个被观察者一起发送数据,合并后按发送顺序执行。
与
concat()
的区别:两者功能一样,区别是concat()
只能最多组合4个被观察者,concatArray()
可以组合大于4个被观察者。
3,concatDelayError()
描述:在使用
concat()
时,如果其中一个观察者发出了error
事件,则其他所有的观察者事件都会停止。而concatDelayError()
就是为了解决这一问题,使用此操作符,即使其中一个观察者发出了error
事件,其他事件会继续发送,直到所有事件发送完毕,才出发onError
。示例:
在正常使用
concat()
发生error时的情况
Observable.concat(
//从1开始,共发送3个,延时1s发送第一个,之后间隔1s发送余下数字
Observable.create(new ObservableOnSubscribe<Integer>() {
@Override
public void subscribe(ObservableEmitter<Integer> emitter) throws Exception {
emitter.onNext(1);
emitter.onNext(2);
emitter.onError(new NullPointerException());
emitter.onComplete();
}
}),
//从11开始,共发送3个,延时1s发送第一个,之后间隔1s发送余下数字
Observable.just(3, 4, 5))
.subscribe(new Observer<Integer>() {
@Override
public void onSubscribe(Disposable d) {
Log.i(TAG,"onSubscribe");
}
@Override
public void onNext(Integer integer) {
Log.i(TAG,"onNext:"+integer);
}
@Override
public void onError(Throwable e) {
Log.i(TAG,"onError");
}
@Override
public void onComplete() {
Log.i(TAG,"onComplete");
}
});
输出:
可以看到,其中一个被观察者发送了error后,另一个会立即停止发送事件。而如果使用concatDelayError()
时:
Observable.concatArrayDelayError(
//从1开始,共发送3个,延时1s发送第一个,之后间隔1s发送余下数字
Observable.create(new ObservableOnSubscribe<Integer>() {
@Override
public void subscribe(ObservableEmitter<Integer> emitter) throws Exception {
emitter.onNext(1);
emitter.onNext(2);
emitter.onError(new NullPointerException());
emitter.onComplete();
}
}),
//从11开始,共发送3个,延时1s发送第一个,之后间隔1s发送余下数字
Observable.just(3, 4, 5))
.subscribe(new Observer<Integer>() {
@Override
public void onSubscribe(Disposable d) {
Log.i(TAG,"onSubscribe");
}
@Override
public void onNext(Integer integer) {
Log.i(TAG,"onNext:"+integer);
}
@Override
public void onError(Throwable e) {
Log.i(TAG,"onError");
}
@Override
public void onComplete() {
Log.i(TAG,"onComplete");
}
});
此时的输出:
4,merge()
描述:合并多个发射物,合并后按时间线并行发射。
示意图:
与
concat()
的区别:concat()
合并后是按顺序串行发射,merge
会让合并的Observables
发射的数据交错示例:
Observable.merge(
//从1开始,共发送3个,延时1s发送第一个,之后间隔1s发送余下数字
Observable.intervalRange(1, 3, 1, 1, TimeUnit.SECONDS),
//从11开始,共发送3个,延时1s发送第一个,之后间隔1s发送余下数字
Observable.intervalRange(11, 3, 1, 1, TimeUnit.SECONDS))
.subscribe(new Consumer<Long>() {
@Override
public void accept(Long value) throws Exception {
Log.i(TAG, "accept:" + value);
}
});
输出:
5,mergeArray()
- 描述:功能同
merge()
,区别在于merge()
只能最多组合4个被观察者,mergeArray()
可组合大于4个被观察者。
6,mergeDelayError()
描述:功能本职上与
concatDelayError
相同,区别只是concat
与merge
的区别,不再示例。示意图:
7,zip()
描述:
zip
操作符返回一个Obversable
,它使用这个函数按顺序结合两个或多个Observables
发射的数据项,然后它发射这个函数返回的结果。它按照严格的顺序应用这个函数。它只发射与发射数据项最少的那个Observable
一样多的数据。示意图:
示例:
Observable.zip(
Observable.just(1, 2, 3),
Observable.just("A", "B", "C", "D"),
new BiFunction<Integer, String, String>() {
@Override
public String apply(Integer integer, String s) throws Exception {
return integer + s;
}
}
).subscribe(new Consumer<String>() {
@Override
public void accept(String s) throws Exception {
Log.i(TAG, "accept:" + s);
}
});
输出:
可以看出,最终事件的数量等于被观察者中发送最少的那个数量。
- 重载
zip(Iterable,FuncN)
zip(Observable,FuncN)
zip(Observable,Observable,Func2)
(最多可以有九个observable参数)
8,zipWith()
描述:
zipWith()
与zip()
的区别只是,zipWith()
不是static的方法,必须由一个observable
对象来调用,而不是直接Observable.
的形式调用。功能与zip()
相同。示意图:
重载:
zipWith(Observable,Func2)
zipWith(Iterable,Func2)
9,combineLatest()
描述:
CombineLatest
操作符行为类似于zip
,但是只有当原始的Observable
中的每一个都发射了一条数据时zip
才发射数据。CombineLatest
则在原始的Observable
中任意一个发射了数据时发射一条数据。当原始Observables
的任何一个发射了一条数据时,CombineLatest
使用一个函数结合它们最近发射的数据,然后发射这个函数的返回值。示意图:
示例:
Observable.combineLatest(
Observable.intervalRange(1, 3, 1, 1, TimeUnit.SECONDS),
Observable.intervalRange(4, 3, 2, 1, TimeUnit.SECONDS),
new BiFunction<Long, Long, Long>() {
@Override
public Long apply(Long l1, Long s) throws Exception {
Log.i(TAG, "发送的数据:" + l1 + "," + s);
return l1 + s;
}
}
).subscribe(new Consumer<Long>() {
@Override
public void accept(Long s) throws Exception {
Log.i(TAG, "accept:" + s);
}
});
输出:
- 重载:
combineLatest(List,FuncN)
combineLatest(Observable,Observable,Func2)
,此方法接受2个到9个observable参数
10,combineLatestDelayError()
- 描述:作用类似于
concatDelayError()/mergeDelayError()
,即错误处理,此处不作过多描述
11,join()
描述:任何时候,只要在另一个
Observable
发射的数据定义的时间窗口内,这个Observable
发射了一条数据,就结合两个Observable
发射的数据。Join
操作符结合两个Observable
发射的数据,基于时间窗口(你定义的针对每条数据特定的原则)选择待集合的数据项。你将这些时间窗口实现为一些Observables
,它们的生命周期从任何一条Observable
发射的每一条数据开始。当这个定义时间窗口的Observable
发射了一条数据或者完成时,与这条数据关联的窗口也会关闭。只要这条数据的窗口是打开的,它将继续结合其它Observable
发射的任何数据项。你定义一个用于结合数据的函数。使用join操作符需要4个参数,分别是:
源Observable所要组合的目标Observable
一个函数,接受从源Observable发射来的数据,并返回一个Observable,这个Observable的生命周期决定了源Observable发射出来数据的有效期
一个函数,接受从目标Observable发射来的数据,并返回一个Observable,这个Observable的生命周期决定了目标Observable发射出来数据的有效期
一个函数,接受从源Observable和目标Observable发射来的数据,并返回最终组合完的数据。
示意图:
示例:
Observable
//源observable
.just(11L)
.join(
//目标observable
Observable.create(new ObservableOnSubscribe<Long>() {
@Override
public void subscribe(ObservableEmitter<Long> emitter) throws Exception {
for (Long i = 1L; i < 6L; i++) {
emitter.onNext(i);
try {
Thread.sleep(1000);
} catch (Exception e) {
e.printStackTrace();
}
}
emitter.onComplete();
}
}),
//这个observable的生命周期决定了源observable发送数据的有效期
new Function<Long, ObservableSource<Long>>() {
@Override
public ObservableSource<Long> apply(Long aLong) throws Exception {
return Observable.timer(3000, TimeUnit.MILLISECONDS);
}
},
//这个observable的生命周期决定了目标observable发送数据的有效期
new Function<Long, ObservableSource<Long>>() {
@Override
public ObservableSource<Long> apply(Long l) throws Exception {
return Observable.timer(2000, TimeUnit.MILLISECONDS);
}
},
//返回最终组合后的数据
new BiFunction<Long, Long, String>() {
@Override
public String apply(Long aLong, Long aLong2) throws Exception {
return aLong + "和" + aLong2;
}
})
.subscribe(new Consumer<String>() {
@Override
public void accept(String s) throws Exception {
Log.i(TAG, "accept:" + s);
}
});
输出:
源observable发送了一条有效期为3s的数据,在这3s时间内,目标observable发送了3条数据,每条有效期2s,在源observable数据的时间窗口内,所以可以组合成observable最终发送。而目标observable发送的剩余的数据,因为发送时源observable的数据已经失效,所以丢弃。
12,joinGroup()
描述:功能与
join()
相同,只是最后组合数据的方法参数不同。示意图:
13,startWith()
描述:如果你想要一个
Observable
在发射数据之前先发射一个指定的数据序列,可以使用StartWith
操作符。(如果你想一个Observable
发射的数据末尾追加一个数据序列可以使用Concat
操作符。示意图:
示例:
Observable.just(5, 6, 7)
.startWith(4)
.subscribe(new Consumer<Integer>() {
@Override
public void accept(Integer s) throws Exception {
Log.i(TAG, "accept:" + s);
}
});
输出:
- 重载:
startWith(T)
startWith(ObservableSource)
,可以添加observable作为参数startWith(Iterable)
14,startWithArray()
- 描述:与
startWith()
相同,只是该方法startWithArray(T... itmes)
可以添加无数参数
15,switchOnNext()
描述:将一个发射多个
Observables
的Observable
转换成另一个单独的Observable
,后者发射那些Observables
最近发射的数据项示意图:
示例:
Observable.switchOnNext(Observable.create(
new ObservableOnSubscribe<ObservableSource<Long>>() {
@Override
public void subscribe(ObservableEmitter<ObservableSource<Long>> emitter) throws Exception {
//每隔1s发射一个小Observable。小Observable从11开始,每1s发射一个整数,一共发射4个
emitter.onNext(Observable.intervalRange(11, 4, 0, 1000, TimeUnit.MILLISECONDS));
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
emitter.onNext(Observable.intervalRange(11, 4, 0, 1000, TimeUnit.MILLISECONDS));
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}))
.subscribe(new Consumer<Long>() {
@Override
public void accept(Long s) throws Exception {
Log.i(TAG, "accept:" + s);
}
});
输出:
第一个Observable每隔1s发射一个数据,总共发射4条数据;第二个Observable正好在第一个Observable发射13的时候产生了,这时候将不再订阅第一个Observable,所以第一个Observable只发射了11和12,后面的数据都被舍弃。