目录
目录
辅助操作
repeat
repeatUntil
delay
delaySubscription
do系列
doOnEach
doOnNext
doOnSubscribe
doOnComplete
doOnError
doOnTerminate
doFinally
doOnDispose
materialize
dematerialize
observeOn
subscribeOn
subscribe
foreach
serialize
Timestamp
timeInterval
timeout
变换操作
map
flatMap
concatMap
cast
groupBy
window
scan
buffer系列
buffer
辅助操作
repeat
不是创建一个Observable,而是重复发射原始,Observable的数据序列,这个序列或者是无限的,或者通过 repeat(n) 指定重复次数
Observable.just("Love", "For", "You!")
.repeat(3)//重复三次
.subscribe(s -> System.out.println(s));
repeatUntil
getAsBoolean 如果返回 true则不repeat false则repeat.主要用于动态控制
Observable.just("Love", "For", "You!")
.repeatUntil(new BooleanSupplier() {
@Override
public boolean getAsBoolean() throws Exception {
System.out.println("getAsBoolean");
count++;
if (count == 3)
return true;
else
return false;
}
}).subscribe(s -> System.out.println(s));
delay
延迟一段指定的时间再发射来自Observable的发射物
注意:delay 不会平移 onError 通知,它会立即将这个通知传递给订阅者,同时丢弃任何待 发射的 onNext 通知。然而它会平移一个 onCompleted 通知
Observable.range(0, 3)
.delay(1400, TimeUnit.MILLISECONDS)
.subscribe(o -> System.out.println("===>" + o + "\t"));
delaySubscription
让你可以延迟订阅原始Observable
Observable.just(1)
.delaySubscription(2000, TimeUnit.MILLISECONDS)
.subscribe(o -> System.out.println("===>" + o + "\t")
, throwable -> System.out.println("===>throwable")
, () -> System.out.println("===>complete")
, disposable -> System.out.println("===>订阅"));
do系列
doOnEach
注册一个回调,它产生的Observable每发射一项数据就会调用它一次
Observable.range(0, 3)
.doOnEach(integerNotification -> System.out.println(integerNotification.getValue()))
.subscribe(o -> System.out.print("===>" + o + "\t"));
日志:
doOnEach:
doOnEach:0===>0
doOnEach:1===>1
doOnEach:2===>2
doOnEach:null
doOnNext
注类似doOnEach 不是接受一个 Notification 参数,而是接受发射的数据项。
Observable.range(0, 3)
.doOnNext(integer -> {
if (integer == 2)
throw new Error("O__O");
System.out.print(integer);
})
.subscribe(o -> System.out.print("===>" + o + "\t")
, throwable -> System.out.print("===>throwable")
, () -> System.out.print("===>complete"));
日志:
0===>0 1===>1 ===>throwable
doOnSubscribe
注册一个动作,在观察者订阅时使用
Observable.range(0, 3)
.doOnSubscribe(disposable -> System.out.print("开始订阅"))
.subscribe(o -> System.out.print("===>" + o + "\t"));
日志:
开始订阅===>0 ===>1 ===>2
doOnComplete
注册一个动作,在观察者OnComplete时使用
Observable.range(0, 3)
.doOnComplete(() -> System.out.print("doOnComplete"))
.subscribe(o -> System.out.print("===>" + o + "\t"));
日志:
===>0 ===>1 ===>2 doOnComplete
doOnError
注册一个动作,在观察者doOnError时使用
Observable.error(new Throwable("?"))
.doOnError(throwable -> System.out.print("throwable"))
.subscribe(o -> System.out.print("===>" + o + "\t"));
日志:
异常信息....
throwable
doOnTerminate
注册一个动作,Observable终止之前会被调用,无论是正 常还是异常终止。
Observable.range(0, 3)
.doOnTerminate(() -> System.out.print("\t doOnTerminate"))
.subscribe(o -> System.out.print("===>" + o + "\t"));
日志:
===>0 ===>1 ===>2 doOnTerminate
doFinally
注册一个动作,当它产生的Observable终止之后会被调用,无论是正常还 是异常终止。在doOnTerminate之后执行
Observable.range(0, 3)
.doFinally(() -> System.out.print("\t doFinally"))
.doOnTerminate(() -> System.out.print("\t doOnTerminate"))
.subscribe(o -> System.out.print("===>" + o + "\t"));
日志:
===>0 ===>1 ===>2 doOnTerminate doFinally
doOnDispose
注册一个动作,当【观察者取消】订阅它生成的Observable它就会被调
注意:貌似需要在 为出现complete和error的时候 dispose才会触发 ~
Disposable ab = Observable.interval(1, TimeUnit.SECONDS)
.take(3)
.doOnDispose(() -> System.out.println("解除订阅"))
.subscribe(o -> System.out.print("===>" + o + "\t"));
ab.dispose();
日志:
解除订阅
materialize
将数据项和事件通知都当做数据项发射
dematerialize
materialize相反
Observable.range(0, 3)
//将Observable转换成一个通知列表。
.materialize()
//与上面的作用相反,将通知逆转回一个Observable
.dematerialize()
.subscribe(o -> System.out.print("===>" + o + "\t"));
observeOn
指定一个观察者在哪个调度器上观察这个Observable
subscribeOn
指定Observable自身在哪个调度器上执行
注意 遇到错误 会立即处理而不是等待下游还没观察的数据, 即onError 通知会跳到(并吞掉)原始Observable发射的数据项前面
Observable.range(0, 3)
.subscribeOn(Schedulers.newThread())
.observeOn(Schedulers.newThread())
.subscribe(o -> System.out.print("===>" + o + "\t"));
subscribe
操作来自Observable的发射物和通知
Javadoc: subscribe()
Javadoc: subscribe(onNext)
Javadoc: subscribe(onNext,onError)
Javadoc: subscribe(onNext,onError,onComplete)
Javadoc: subscribe(onNext,onError,onComplete,onSubscribe)
Javadoc: subscribe(Observer)
Javadoc: subscribe(Subscriber)
foreach
forEach 方法是简化版的 subscribe ,你同样可以传递一到三个函数给它,解释和传递给 subscribe 时一样.
不同的是,你无法使用 forEach 返回的对象取消订阅。也没办法传递一个可以用于取消订阅 的参数
Observable.range(0, 3)
//subscribe的简化版本 没啥用
.forEach(o -> System.out.println("===>" + o + "\t"));
serialize
保证上游下游同一线程 ,防止不同线程下 onError 通知会跳到(并吞掉)原始Observable发射的数据项前面的错误行为
Observable.range(0, 3)
.serialize()
.subscribe(o -> System.out.print("===>" + o + "\t"));
Timestamp
它将一个发射T类型数据的Observable转换为一个发射类型 为Timestamped 的数据的Observable,每一项都包含数据的原始发射时间
Observable.interval(100, TimeUnit.MILLISECONDS)
.take(3)
.timestamp()
.subscribe(o -> System.out.println("===>" + o + "\t")
, throwable -> System.out.println("===> throwable")
, () -> System.out.println("===> complete")
, disposable -> System.out.println("===> 订阅"));
日志:
===> 订阅
===>Timed[time=1501224256554, unit=MILLISECONDS, value=0]
===>Timed[time=1501224256651, unit=MILLISECONDS, value=1]
===>Timed[time=1501224256751, unit=MILLISECONDS, value=2]
===> complete
timeInterval
一个发射数据的Observable转换为发射那些数据发射时间间隔的Observable
1
Observable.interval(100, TimeUnit.MILLISECONDS)
.take(3)
// 把发送的数据 转化为 相邻发送数据的时间间隔实体
.timeInterval()
// .timeInterval(Schedulers.newThread())
.subscribe(o -> System.out.println("===>" + o + "\t")
, throwable -> System.out.println("===>throwable")
, () -> System.out.println("===>complete")
, disposable -> System.out.println("===>订阅"));
日志:
===>订阅
===>Timed[time=113, unit=MILLISECONDS, value=0]
===>Timed[time=102, unit=MILLISECONDS, value=1]
===>Timed[time=97, unit=MILLISECONDS, value=2]
===>complete
timeout
变体:过了一个指定的时长仍没有发射数据(不是仅仅考虑第一个),它会发一个错误
Observable.interval(100, TimeUnit.MILLISECONDS)
// 过了一个指定的时长仍没有发射数据(不是仅仅考虑第一个),它会发一个错误
.timeout(50, TimeUnit.MILLISECONDS)
.subscribe(o -> System.out.println("===>" + o + "\t")
, throwable -> System.out.println("===>timeout throwable")
, () -> System.out.println("===>timeout complete")
, disposable -> System.out.println("===>timeout 订阅"));
timeout:
===>timeout 订阅
===>timeout throwable
变体 备用Observable:过了一个指定的时长仍没有发射数据(不是仅仅考虑第一个),它会发一个错误
Observable<Integer> other;
Observable.empty()
// 过了一个指定的时长仍没有发射数据(不是仅仅考虑第一个),他会用备用Observable 发送数据,本身的会发送一个compelte
.timeout(50, TimeUnit.MILLISECONDS, other = Observable.just(2, 3, 4))
.subscribe(o -> System.out.println("===>" + o + "\t")
, throwable -> System.out.println("===>timeout2 throwable")
, () -> System.out.println("===>timeout2 complete")
, disposable -> System.out.println("===>timeout2 订阅"));
other.subscribe(o -> System.out.println("k ===>" + o + "\t"));
timeout2:
===>timeout2 订阅
===>timeout2 complete
k ===>2
k ===>3
k ===>4
变换操作
map
对Observable发射的每一项数据应用一个函数,执行变换操作,就是方形过渡到圆形
Observable.just(1,2)
.map(integer -> "This is result " + integer)
.subscribe(s -> System.out.println(s));
flatMap
将一个发射数据的Observable变换为多个Observables,然后将它们发射的数据合并后放进一个单独的Observable
mapper:根据发射数据映射成Observable
combiner: 用来合并 的
注意:FlatMap 对这些Observables发射的数据做的是合并( merge )操作,因此它们可能是交 错的。
Observable.just(1, 2, 3)
.flatMap(integer -> Observable.range(integer * 10, 2)
, (a, b) -> {
//a : 原始数据的 just(1,2,3) 中的值
//b : 代表 flatMap后合并发送的数据的值
System.out.print("\n a:" + a + "\t b:" + b);
//return flatMap发送的值 ,经过处理后 而发送的值
return a + b;
})
.subscribe(s -> System.out.print("\t"+s));
日志:
<!-- 这里有顺序是因为没有在其他线程执行 -->
a:1 b:10 11
a:1 b:11 12
a:2 b:20 22
a:2 b:21 23
a:3 b:30 33
a:3 b:31 34
concatMap
类似FlatMap但是保证顺序 因为没有合并操作!
Observable.just(1, 2, 3)
.concatMap(integer -> Observable.range(integer * 10, 2))
.subscribe(s -> System.out.print("\t"+s));
cast
在发射之前强制将Observable发射的所有数据转换为指定类型
Observable.just(1, 2, "string")
.cast(Integer.class)//订阅之后才能发横强转
.subscribe(integer -> System.out.println(integer)
, throwable -> System.out.println(throwable.getMessage()));
groupBy
通过keySelector的apply的值当做key 进行分组,发射GroupedObservable(有getKey()方法)的group 通过group继续订阅取得其组内的值;
1
keySelector:通过这个的返回值 当做key进行分组
valueSelector:value转换
Observable.range(0, 10)
.groupBy(integer -> integer % 2, integer -> "(" + integer + ")")
.subscribe(group -> {
group.subscribe(integer -> System.out.println(
"key:" + group.getKey() + "==>value:" + integer));
});
日志:
key:0==>value:(0)
key:1==>value:(1)
key:0==>value:(2)
key:1==>value:(3)
key:0==>value:(4)
key:1==>value:(5)
key:0==>value:(6)
key:1==>value:(7)
key:0==>value:(8)
key:1==>value:(9)
window
依照此范例 每三秒收集,Observable在此时间内发送的值。组装成Observable发送出去。
1
Observable.interval(1, TimeUnit.SECONDS).take(7)
//返回值 Observable<Observable<T>> 即代表 发送Observable<T>
.window(3, TimeUnit.SECONDS)
.subscribeOn(Schedulers.io())
.observeOn(Schedulers.io())
.subscribe(integerObservable -> {
System.out.println(integerObservable);
integerObservable.subscribe(integer -> System.out.println(integerObservable+"===>"+integer));
});
日志:
为什么不是 345一起? 因为会有太细微的时间差。例如5如果在多线程切换的时候是超过3秒的1毫秒则就尴尬了~
io.reactivex.subjects.UnicastSubject@531c3d1c
io.reactivex.subjects.UnicastSubject@531c3d1c===>0
io.reactivex.subjects.UnicastSubject@531c3d1c===>1
io.reactivex.subjects.UnicastSubject@531c3d1c===>2
io.reactivex.subjects.UnicastSubject@2ea0f969
io.reactivex.subjects.UnicastSubject@2ea0f969===>3
io.reactivex.subjects.UnicastSubject@2ea0f969===>4
io.reactivex.subjects.UnicastSubject@2d30de03
io.reactivex.subjects.UnicastSubject@2d30de03===>5
io.reactivex.subjects.UnicastSubject@2d30de03===>6
scan
连续地对数据序列的每一项应用一个函数,然后连续发射结果
感觉就是发送一个有 累加(函数) 过程序列
* initialValue(可选) 其实就是放到 原始数据之前发射。
* a 原始数据的中的值
* b 则是最后应用scan函数后发送的值
Observable.just(1, 4, 2)
//7是用来 对于第一次的 a的值
.scan(7, (a, b) -> {
//b 原始数据的 just(1,4,2) 中的值
//a 则是最后应用scan 发送的值
System.out.format("a:%d * b:%d\n", a, b);
return a * b;
})
.subscribe(integer -> System.out.println("===>:"+integer));
日志:
===>:7
a:7 * b:1
===>:7
a:7 * b:4
===>:28
a:28 * b:2
===>:56
buffer系列
buffer
变体 count系列
1. 范例:发射[1-10]
2. buffer count 2 skip 1,结果 [1,2] [2,3] [3,4] 3=2*1+1
3. buffer count 2 skip 2,结果 [1,2] [3,4] [5,6] 5=2*2+1
4. buffer count 2 skip 3,结果 [1,2] [4,5] [7,8] 7=2*3+1;
1) count:缓存的数量
2) skip:每个缓存创建的间隔数量
这代表 每次初始偏移量 每次真正的起始值=fistValue+skip*skipCount;
注意skip不能小于0
可以小于count这样就会导致每个发送的list之间的值会有重复
可以大于count这样就会导致每个发送的list之间的值和原有的值之间会有遗漏
可以等于count就你懂的了
3) bufferSupplier:自定义缓存装载的容器
Observable.range(1, 10)
.buffer(2, 1,() -> new ArrayList<>())//有默认的装载器
<!-- 其他方法 -->
<!-- .buffer(2)//skip 默认和count一样 -->
<!-- .buffer(2, () -> new ArrayList<>())-->
.subscribe(integers -> System.out.println(integers));
解析:每发射1个。创建一个发射物list buffer,每个buffer缓存2个,收集的存入list后发送。
变体 time系列
1) timespan:缓存的时间
2) timeskip:每个缓存创建的间隔时间 同skip 可以小于大于等于timespan
Observable.interval(500, TimeUnit.MILLISECONDS).take(7)
.buffer(3, 2, TimeUnit.SECONDS, Schedulers.single(),
Functions.createArrayList(16))
.subscribe(integers -> System.out.println(integers));
解析:每两秒创建一个发射物list buffer,每个buffer缓存三秒 收集的存入list后发送。
日志:
[0, 1, 2, 3, 4]
[4, 5, 6]
3) 变体 自定义buffer创建和收集时间
4) bufferOpenings:每当 bufferOpenings 发射了一个数据时,它就 创建一个新的 List,开始装入之后的发射数据
5) closingSelector:每当 closingSelector 发射了一个数据时,就结束装填数据 发射List。
<!-- 范例和time系列的就一样了 -->
Consumer<Long> longConsumer = aLong -> System.out.println("开始创建 bufferSupplier");
Consumer<Long> longConsumer2 = aLong -> System.out.println("结束收集");
Observable.interval(500, TimeUnit.MILLISECONDS).take(7)
// .doOnNext(aLong -> System.out.println("原始发射物:" + aLong))
.buffer(Observable.interval(2, TimeUnit.SECONDS)
.startWith(-1L)//为了刚开始就发射一次
.take(2)//多余的我就不创建了
.doOnNext(longConsumer)
, aLong -> Observable.timer(3, TimeUnit.SECONDS)
.doOnNext(longConsumer2)
, () -> new ArrayList<>())
.subscribe(integers -> System.out.println("buffer发射物" + integers));
日志:
openings:
开始创建 bufferSupplier
开始创建 bufferSupplier
结束收集
buffer发射物[0, 1, 2, 3, 4]
buffer发射物[4, 5, 6]
变体 仅仅bufer创建时间
boundarySupplier 因为发送一个值代表上个缓存的发送 和这个缓存的创建
*注释: 这个缓存是连续的, 因为发送一个值代表上个缓存的发送 和这个缓存的创建
有发射物的时候 没缓存就创建了 就是 默认第一个发射物的时候由内部创建
注意 如果不发送事件缓存 存满了 会自动发送出去的
Observable.interval(500, TimeUnit.MILLISECONDS).take(7)
.buffer(() -> Observable.timer(2, TimeUnit.SECONDS)
.doOnNext(aLong -> System.out.println("开始创建 bufferSupplier"))
, () -> new ArrayList<Object>())
.subscribe(integers -> System.out.println(integers));
日志:
开始创建 bufferSupplier
[0, 1, 2]
[3, 4, 5, 6]