基本操作格式:
1. buffer(count)
2. buffer(count, skip)
3. buffer(bufferClosingSelector和buffer(boundary)
4. buffer(bufferOpenings, bufferClosingSelector)
5. buffer(timespan, unit[, scheduler])
6. buffer(timespan, unit, count[, scheduler])
7. buffer(timespan, timeshift, unit[, scheduler])
官方流程图:
Buffer操作符将一个Observable变换为另一个,原来的Observable正常发射数据,变换产生的Observable发射这些数据的缓存集合。Buffer操作符在很多语言特定的实现中有很多种变体,它们在如何缓存这个问题上存在区别。
注意:如果原来的Observable发射了一个onError通知,Buffer会立即传递这个通知,而不是首先发射缓存的数据,即使在这之前缓存中包含了原始Observable发射的数据。
buffer将数据缓存到一个集合当中,然后在适当的时机一起发送。
1、 buffer(count)
根据个数来缓冲,每次缓冲2个数据,再发射出去
Observable.range(0,5)
.buffer(2)
.subscribe(i-> Log.d("buffer","buffer(2)—>"+String.valueOf(i)));
运行结果:
[0, 1]
[2, 3]
[4]
2、 buffer(count, skip)
根据时间来缓冲,每隔2个数据开始一次缓冲,每次缓冲3个数据
Observable.range(0,10)
.subscribe(i-> Log.d("buffer","buffer(2,3)->"+String.valueOf(i)));
运行结果:
[0, 1, 2]
[4, 5, 6]
[8, 9]
3、 buffer(bufferClosingSelector)和buffer(boundary)
//buffer(Observable<B> boundary)
buffer传的参数是一个Observable类型的对象
Observable.interval(100,TimeUnit.MILLISECONDS)
.take(10)
.buffer(Observable.interval(250,TimeUnit.MILLISECONDS))
.subscribe(i-> Log.d("buffer","buffer1->"+String.valueOf(i)));
//buffer(Func0<? extends Observable<? extends TClosing>> //bufferClosingSelector)
buffer传的参数是一个Func0类型对象
Observable.interval(100,TimeUnit.MILLISECONDS)
.take(10)
.buffer(()->Observable.interval(250,TimeUnit.MILLISECONDS))
.subscribe(i-> Log.d("buffer","buffer2->"+String.valueOf(i)));
他们两个的区别是:只有当有Subscriber 订阅的时候,使用函数返回的信号 Observable 才开始执行。
运行结果:
[0, 1]
[2, 3]
[4, 5, 6]
[7, 8]
[9]
4、 buffer(bufferOpenings, bufferClosingSelector)
这个操作函数有两个参数,第一个 bufferOpenings 参数为一个 Observable,只要该 Observable 发射了一个数据,就开始一个新的缓冲。每个缓冲到的数据会传递给第二个函数参数 bufferClosingSelector ,bufferClosingSelector 参数为一个函数,该函数创建一个新的 Observable,当这个 Observable 发射数据的时候表明这个缓冲结束。
Observable.interval(100, TimeUnit.MILLISECONDS)
.take(10)
.buffer(Observable.interval(250,TimeUnit.MILLISECONDS),aLong->Observable.timer(200,TimeUnit.MILLISECONDS))
.subscribe(i-> Log.d("buffer","buffer->"+String.valueOf(i)));
运行结果:
[2, 3]
[4, 5]
[7, 8]
[9]
5、 buffer(timespan, unit[, scheduler])
下面的示例中,每隔100毫秒发射一个数据,使用200毫秒的时间窗口来缓冲数据
Observable.interval(100,TimeUnit.MILLISECONDS)
.take(10)
.buffer(200,TimeUnit.MILLISECONDS)
.subscribe(i-> Log.d("buffer","buffer(200,TimeUnit.MILLISECONDS)->"+String.valueOf(i)));
运行结果:
[0]
[1, 2]
[3, 4]
[5, 6]
[7, 8]
[9]
注意:每个时间窗口发射的数据个数可能是不一样的。在某个时间窗口内,也可能没有数据发射。
6、 buffer(timespan, unit, count[, scheduler])
(1)当达到缓冲的时间200毫秒的就发射数据不管缓冲个数有没有满
(2)当达到缓冲的个数时就发射数据不管缓冲的时间有没有到
Observable.range(0,10)
.buffer(200,TimeUnit.MILLISECONDS,2)
.subscribe(i-> Log.d("buffer","buffer(200,TimeUnit.MILLISECONDS,2)->"+String.valueOf(i)));
运行结果:
[0, 1]
[2, 3]
[4, 5]
[6, 7]
[8, 9]
[]
7、 buffer(timespan, timeshift, unit[, scheduler])
当 timespan > timeshift 的时候,缓冲的数据重叠了
当 timespan < timeshift 的时候,缓冲的数据有丢失
当 timespan = timeshift 的时候,和前面看到的简单版本一样
下一个示例中,每隔 200毫秒开启下一个缓冲,每个缓冲时间窗口是 350毫秒。所以两个缓冲之间会有 150毫秒的重叠。
Observable.interval(100,TimeUnit.MILLISECONDS)
.take(10)
.buffer(350,200,TimeUnit.MILLISECONDS)
.subscribe(i-> Log.d("buffer","buffer(350,200,TimeUnit.MILLISECONDS)->"+String.valueOf(i)));
运行结果:
[0, 1, 2]
[2, 3, 4]
[3, 4, 5, 6]
[5, 6, 7, 8]
[7, 8, 9]
[9]