Rxjava2 concat

99 阅读3分钟

concat操作符可以有序的发送我们的数据。

在例子中,o1延时4s后发射数据,o2延时2s后发射数据,但是输出的结果却是1,2,3,4。

        Observable o1 = Observable.just(1,2).delay(4,TimeUnit.SECONDS);
        Observable o2 = Observable.just(3,4).delay(2,TimeUnit.SECONDS);
        Observable.concat(o1,o2).subscribe(new Observer() {
            @Override
            public void onSubscribe(@NotNull Disposable d) {
                System.out.println("onSubscribe");
            }

            @Override
            public void onNext(@NotNull Object 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");
            }
        });

看看源码中是如何操作的。

   public static <T> Observable<T> concat(ObservableSource<? extends T> source1, 
   			ObservableSource<? extends T> source2) {
       ...
        return concatArray(source1, source2);
    }
  public static <T> Observable<T> concatArray(ObservableSource<? extends T>... sources) {
        ...
        return RxJavaPlugins.onAssembly(new ObservableConcatMap(fromArray(sources), 
        	Functions.identity(), bufferSize(), ErrorMode.BOUNDARY));
    }

代码一路下来,ObservableConcatMap, mapper是一个转换对象,这里的作用就是简单给出原始对象,没有转换。

public final class ObservableConcatMap<T, U> extends AbstractObservableWithUpstream<T, U> {
    final Function<? super T, ? extends ObservableSource<? extends U>> mapper;
    final int bufferSize;

    final ErrorMode delayErrors;

    public ObservableConcatMap(ObservableSource<T> source, Function<? super T, ? extends ObservableSource<? extends U>> mapper,
            int bufferSize, ErrorMode delayErrors) {
        super(source);
        this.mapper = mapper;
        this.delayErrors = delayErrors;
        this.bufferSize = Math.max(8, bufferSize);
    }

    @Override
    public void subscribeActual(Observer<? super U> observer) {
	...
         source.subscribe(new ConcatMapDelayErrorObserver<T, U>(observer, mapper, bufferSize, delayErrors == ErrorMode.END));
    }

调用subscribe就会执行到subscribeActual内部,这里的source其实是ObservableFromArray对象,array就是我们例子中包含o1o2的数组。在上面的代码中调用source.subscribe(...)后执行ObservableFromArraysubscribeActual方法,

public final class ObservableFromArray<T> extends Observable<T> {
    final T[] array;
    public ObservableFromArray(T[] array) {
        this.array = array;
    }

    @Override
    public void subscribeActual(Observer<? super T> observer) {
        FromArrayDisposable<T> d = new FromArrayDisposable<T>(observer, array);

        observer.onSubscribe(d);

        if (d.fusionMode) {
            return;
        }

        d.run();
    }
   ...
}

此时还不会走到run方法中,需要调用FromArrayDisposablerequestFusion方法。

 public int requestFusion(int mode) {
            if ((mode & SYNC) != 0) {
                fusionMode = true;
                return SYNC;
            }
            return NONE;
        }

随着observer.onSubscribe(d);的调用,代码来到ConcatMapDelayErrorObserveronSubscribe方法。

 public void onSubscribe(Disposable d) {
            if (DisposableHelper.validate(this.upstream, d)) {
                this.upstream = d;
                if (d instanceof QueueDisposable) {
                    @SuppressWarnings("unchecked")
                    QueueDisposable<T> qd = (QueueDisposable<T>) d;

                    int m = qd.requestFusion(QueueDisposable.ANY);//可以发送数据了
                    if (m == QueueDisposable.SYNC) {
                        fusionMode = m;
                        queue = qd;
                        done = true;

                        downstream.onSubscribe(this);

                        drain();
                        return;
                    }

                   ...
            }
        }

来到核心的部分,tillTheEnd表示是否需要把数据发送完再发送error,done表示是否已经结束,

void drain() {
 	   //用于多线程安全访问
            if (getAndIncrement() != 0) {
                return;
            }

            Observer<? super R> actual = this.downstream;
            SimpleQueue<T> queue = this.queue;
            AtomicThrowable error = this.error; 
            //不停的修改原子变量,成功后再退出。
            for (;;) {

                if (!active) {

                    if (cancelled) {
                        // 如果被dispose了,也就没有必要继续发送数据了。
                        queue.clear();
                        return;
                    }

                    if (!tillTheEnd) {
                       //后续事件也不要了,直接结束
                        Throwable ex = error.get();
                        if (ex != null) {
                            queue.clear();
                            cancelled = true;
                            actual.onError(error.terminate());
                            return;
                        }
                    }

                    boolean d = done;

                    T v;

                    try {
                       // 这里的queue就是FromArrayDisposable对象的实例,里面有个数组,存储这我们例子中的o1与o2
                        v = queue.poll();
                    } catch (Throwable ex) {
                        Exceptions.throwIfFatal(ex);
                        cancelled = true;
                        this.upstream.dispose();
                        error.addThrowable(ex);
                        actual.onError(error.terminate());
                        return;
                    }

                    //获取例子中的o1或者o2
                    boolean empty = v == null;

                    if (d && empty) {
                       //一直把queue里的数据发送完
                       // 如果有错,就会onError
                       //没有出错,就会onComplete
                        cancelled = true;
                        Throwable ex = error.terminate();
                        if (ex != null) {
                            actual.onError(ex);
                        } else {
                            actual.onComplete();
                        }
                        return;
                    }

                    if (!empty) {

                        ObservableSource<? extends R> o;

                        try {
                          //这里的o就是v实例,没有转换
                            o = ObjectHelper.requireNonNull(mapper.apply(v), "The mapper returned a null ObservableSource");
                        } catch (Throwable ex) {
                            Exceptions.throwIfFatal(ex);
                            cancelled = true;
                            this.upstream.dispose();
                            queue.clear();
                            error.addThrowable(ex);
                            actual.onError(error.terminate());
                            return;
                        }

                        if (o instanceof Callable) {
                            R w;

                            try {
                                w = ((Callable<R>)o).call();
                            } catch (Throwable ex) {
                                Exceptions.throwIfFatal(ex);
                                error.addThrowable(ex);
                                continue;
                            }

                            if (w != null && !cancelled) {
                                actual.onNext(w);
                            }
                            continue;
                        } else {
                            active = true;
                            //让我们例子中的o1与o2订阅observer,注意是顺序订阅
                            //o1先订阅,等到o1把数据发送完毕后,drain方法会被调用,接下来o2
                            // 这就是数据顺序发送的原因。
                            o.subscribe(observer);
                        }
                    }
                }


		//原子更新成功,退出循环,等着下次调用drain
                if (decrementAndGet() == 0) {
                    break;
                }
            }
        }

例子中的o1与o2都是订阅的observer,这里的就是DelayErrorInnerObserver对象,内部有个downstream实例,每次o1或者o2发送数据,调用onNext方法,就会把数据发送到下游,等到数据发送完毕,会调用onComplete方法,这样就又调用了drain方法。

static final class DelayErrorInnerObserver<R> extends AtomicReference<Disposable> implements Observer<R> {

            private static final long serialVersionUID = 2620149119579502636L;

            final Observer<? super R> downstream;

            final ConcatMapDelayErrorObserver<?, R> parent;

            DelayErrorInnerObserver(Observer<? super R> actual, ConcatMapDelayErrorObserver<?, R> parent) {
                this.downstream = actual;
                this.parent = parent;
            }

            @Override
            public void onSubscribe(Disposable d) {
                DisposableHelper.replace(this, d);
            }

            @Override
            public void onNext(R value) {
                downstream.onNext(value);
            }

            @Override
            public void onError(Throwable e) {
                ConcatMapDelayErrorObserver<?, R> p = parent;
                if (p.error.addThrowable(e)) {
                    if (!p.tillTheEnd) {
                        p.upstream.dispose();
                    }
                    p.active = false;
                    p.drain();
                } else {
                    RxJavaPlugins.onError(e);
                }
            }

            @Override
            public void onComplete() {
                ConcatMapDelayErrorObserver<?, R> p = parent;
                p.active = false;
                p.drain();
            }

            void dispose() {
                DisposableHelper.dispose(this);
            }
        }