Rxjava2 buffer

189 阅读2分钟

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表示跳过多少数据,一会再看skipcount不一致的情形,现在两个值是一样的。 我们看看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版本