buffer操作符会把数据打包成List发出来,而不像平时一个一个的发送。
第一种情形: skip与count相等
Observable<Integer> observable = Observable.range(1,30);
observable.buffer(3).subscribe(new Observer<List<Integer>>() {
@Override
public void onSubscribe(@NotNull Disposable d) {
System.out.println("onSubscribe");
}
@Override
public void onNext(@NotNull List<Integer> o) {
System.out.println("onNext " + o);
}
@Override
public void onError(@NotNull Throwable e) {
System.out.println("onError " + e.getMessage());
}
@Override
public void onComplete() {
System.out.println("onComplete");
}
});
输出结果
onSubscribe
onNext [1, 2, 3]
onNext [4, 5, 6]
onNext [7, 8, 9]
onNext [10, 11, 12]
onNext [13, 14, 15]
onNext [16, 17, 18]
onNext [19, 20, 21]
onNext [22, 23, 24]
onNext [25, 26, 27]
onNext [28, 29, 30]
onComplete
查看源码
public final Observable<List<T>> buffer(int count) {
return buffer(count, count);
}
public final Observable<List<T>> buffer(int count, int skip) {
return buffer(count, skip, ArrayListSupplier.<T>asCallable());
}
public final <U extends Collection<? super T>> Observable<U> buffer(int count, int skip, Callable<U> bufferSupplier) {
...
return RxJavaPlugins.onAssembly(new ObservableBuffer<T, U>(this, count, skip, bufferSupplier));
}
ArrayListSupplier.<T>asCallable()的作用就是提供ArrayList<Object>,数据就会放进到这个ArrayList中。
public final class ObservableBuffer<T, U extends Collection<? super T>> extends AbstractObservableWithUpstream<T, U> {
...
@Override
protected void subscribeActual(Observer<? super U> t) {
if (skip == count) {
BufferExactObserver<T, U> bes = new BufferExactObserver<T, U>(t, count, bufferSupplier);
if (bes.createBuffer()) {
source.subscribe(bes);
}
} else {
source.subscribe(new BufferSkipObserver<T, U>(t, count, skip, bufferSupplier));
}
}
...
}
skip表示跳过多少数据,一会再看skip与count不一致的情形,现在两个值是一样的。
我们看看BufferExactObserver中的的createBuffer方法,里面的b就是bufferSupplier提供的ArrayList<Object>,方法的名字顾名思义,创建一个buffer。
boolean createBuffer() {
U b;
try {
b = ObjectHelper.requireNonNull(bufferSupplier.call(), "Empty buffer supplied");
} catch (Throwable t) {
Exceptions.throwIfFatal(t);
buffer = null;
if (upstream == null) {
EmptyDisposable.error(t, downstream);
} else {
upstream.dispose();
downstream.onError(t);
}
return false;
}
buffer = b;
return true;
}
订阅开始,发送数据,不断的将数据添加到buffer中,count表示buffer的最大容量,注意++size,就是if ((++size) >= count),到达count就会发送给下游,此时的b就是ArrayList<Integer>,然后重置size,再创建一个新的buffer。
public void onNext(T t) {
U b = buffer;
if (b != null) {
b.add(t);
if (++size >= count) {
downstream.onNext(b);
size = 0;
createBuffer();
}
}
}
第二种情形: skip与count不相等
Observable<Integer> observable = Observable.range(1,30);
observable.buffer(3,2).subscribe(new Observer<List<Integer>>() {
@Override
public void onSubscribe(@NotNull Disposable d) {
System.out.println("onSubscribe");
}
@Override
public void onNext(@NotNull List<Integer> o) {
System.out.println("onNext " + o);
}
@Override
public void onError(@NotNull Throwable e) {
System.out.println("onError " + e.getMessage());
}
@Override
public void onComplete() {
System.out.println("onComplete");
}
});
输出
onSubscribe
onNext [1, 2, 3]
onNext [3, 4, 5]
onNext [5, 6, 7]
onNext [7, 8, 9]
onNext [9, 10, 11]
onNext [11, 12, 13]
onNext [13, 14, 15]
onNext [15, 16, 17]
onNext [17, 18, 19]
onNext [19, 20, 21]
onNext [21, 22, 23]
onNext [23, 24, 25]
onNext [25, 26, 27]
onNext [27, 28, 29]
onNext [29, 30]
onComplete
直接到源码
source.subscribe(new BufferSkipObserver<T, U>(t, count, skip, bufferSupplier));
例子中skip是2,每隔2个数据就会创建一个新的ArrayList<Integer>,并且将这个对象放进一个
buffers对象(ArrayDeque)中,每发送一个数据,都会遍历buffers,将数据放到ArrayList<Integer>中,一直到ArrayList<Integer>数量达到count。
public void onNext(T t) {
if (index++ % skip == 0) {
U b;
try {
b = ObjectHelper.requireNonNull(bufferSupplier.call(), "The bufferSupplier returned a null collection. Null values are generally not allowed in 2.x operators and sources.");
} catch (Throwable e) {
buffers.clear();
upstream.dispose();
downstream.onError(e);
return;
}
buffers.offer(b);
}
Iterator<U> it = buffers.iterator();
while (it.hasNext()) {
U b = it.next();
b.add(t);
if (count <= b.size()) {
it.remove(); //从队列中移除
downstream.onNext(b);
}
}
}
从上面代码看出,只有到达count才会发送数据。如果最后一个没有达到容量怎么办?
不用担心,看看onComplete方法,会把最后的数据弹出来。
public void onComplete() {
while (!buffers.isEmpty()) {
downstream.onNext(buffers.poll());
}
downstream.onComplete();
}
基于2.2.4版本