RxJava操作符--concat

717 阅读3分钟

concat: Concat会从两个或多个Observable发射出去,而不会交错它们。发射数据时,它将保持可观察者的顺序。这意味着它将发出第一个可观察项的所有项,然后将发出第二个可观察项的所有项,依此类推。

先写一个demo

 Observable<Integer> odds = Observable.just(1,1,1);
        Observable<Integer> even = Observable.just(2,2);

        Observable
                .concat(odds,even)
                .subscribe(new Consumer<Integer>() {
                    @Override
                    public void accept(Integer integer) throws Exception {
                        Log.d(TAG, "accept: " + integer);
                    }
                });
  1. Observable 的 subscribe 方法
 */
    @CheckReturnValue
    @SchedulerSupport(SchedulerSupport.NONE)
    public final Disposable subscribe(Consumer<? super T> onNext, Consumer<? super Throwable> onError,
            Action onComplete, Consumer<? super Disposable> onSubscribe) {
        LambdaObserver<T> ls = new LambdaObserver<T>(onNext, onError, onComplete, onSubscribe);

        subscribe(ls);

        return ls;
    }
  • 将Consumer等包装成LambdaObserver
  • 执行subscribe,这个subscribe的执行者是ObservableConcatMap
  1. ObservableConcatMap的subscribeActual方法
 @Override
    public void subscribeActual(Observer<? super U> observer) {

        if (ObservableScalarXMap.tryScalarXMapSubscribe(source, observer, mapper)) {
            return;
        }

        if (delayErrors == ErrorMode.IMMEDIATE) {
            SerializedObserver<U> serial = new SerializedObserver<U>(observer);
            source.subscribe(new SourceObserver<T, U>(serial, mapper, bufferSize));
        } else {
            source.subscribe(new ConcatMapDelayErrorObserver<T, U>(observer, mapper, bufferSize, delayErrors == ErrorMode.END));
        }
    }
  • 将LambdaObserver 包装成ConcatMapDelayErrorObserver
  • 执行subscribe,这个subscribe的执行者是ObservableFromArray
  1. ObservableFromArray 的subscribeActual方法
 @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();
    }
  • 将observer包装成FromArrayDisposable
  • 调用observer,也就是ConcatMapDelayErrorObserver的onSubcsribe方法 3-1. ConcatMapDelayErrorObserveronSubcsribe方法
 @Override
        public void onSubscribe(Disposable d) {
            if (DisposableHelper.validate(this.upstream, d)) {
            ****upstream 是 FromArrayDisposable
                this.upstream = d;
            ****FromArrayDisposable 继承QueueDisposable,所以满足条件
                if (d instanceof QueueDisposable) {
                    @SuppressWarnings("unchecked")
                    QueueDisposable<T> qd = (QueueDisposable<T>) d;
            **** 计算m的值,结果为SYNC
                    int m = qd.requestFusion(QueueDisposable.ANY);
            **** 进入次条件
                    if (m == QueueDisposable.SYNC) {
                        sourceMode = m;
                        queue = qd;
                        done = true;

                        downstream.onSubscribe(this);
            **** 执行drain方法并返回
                        drain();
                        return;
                    }
            **** 以下代码省略
            }
        }

3-1-1 看drain方法

 void drain() {
            if (getAndIncrement() != 0) {
                return;
            }
            ****actual为downstrem,是LambdaObserver
            Observer<? super R> actual = this.downstream;
            SimpleQueue<T> queue = this.queue;
            AtomicThrowable error = this.error;

            for (;;) {

                if (!active) {

                    if (cancelled) {
                        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 {
                    v 是 FromArrayArray 对象
                        v = queue.poll();
                    } catch (Throwable ex) {
                        Exceptions.throwIfFatal(ex);
                        cancelled = true;
                        this.upstream.dispose();
                        error.addThrowable(ex);
                        actual.onError(error.terminate());
                        return;
                    }

                    boolean empty = v == null;

                    if (d && empty) {
                        cancelled = true;
                        Throwable ex = error.terminate();
                        if (ex != null) {
                            actual.onError(ex);
                        } else {
                            actual.onComplete();
                        }
                        return;
                    }

                    if (!empty) {

                        ObservableSource<? extends R> o;

                        try {
                            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 {
                    **** 调用FromArrayArray的subscribe方法 ,observer = new DelayErrorInnerObserver<R>(actual, this);
                            active = true;
                            o.subscribe(observer);
                        }
                    }
                }

                if (decrementAndGet() == 0) {
                    break;
                }
            }
        }

3-1-2 看看poll方法干了什么?

  public T poll() {
            int i = index;
            T[] a = array;
            if (i != a.length) {
                index = i + 1;
                return ObjectHelper.requireNonNull(a[i], "The array element is null");
            }
            return null;
        }

可以看到在这里将Observable的数组进行遍历,然后取出来,随意我们说concat是顺序执行的原因也就是在这里了,

3-2 调用ObservableFromArray的subscribe方法,基本重复上述过程,但是和之前的对象是不一样的

@Override
    public void subscribeActual(Observer<? super T> observer) {
    **** observer 是 DelayErrorInnerObserver,array 是 之前的 数组 {1,1,1}
        FromArrayDisposable<T> d = new FromArrayDisposable<T>(observer, array);

        observer.onSubscribe(d);

        if (d.fusionMode) {
            return;
        }

        d.run();
    }

3-3 调用 run方法

void run() {
            T[] a = array;
            int n = a.length;

            for (int i = 0; i < n && !isDisposed(); i++) {
                T value = a[i];
                if (value == null) {
                    downstream.onError(new NullPointerException("The " + i + "th element is null"));
                    return;
                }
                downstream 是 DelayErrorInnerObserver
                downstream.onNext(value);
            }
            if (!isDisposed()) {
                downstream.onComplete();
            }
        }

这里的downstream是DelayErrorInnerObserver,然后直接传到LambdaObserver,再到程序中定义的Consumer的accept方法执行。 3-4 调用downstream,也就是DelayErrorInnerObserver的onComplete方法

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

指向完毕后,因为3-1-1是个for死循环,所以程序节点又回到了3-1-1,那么通过v = queue.poll()又拿到了第二个OberverableFromArray对象,继续指令上述3-2----3-3的流程 执行完毕,退出for循环,程序节点跳转至3中,

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

        observer.onSubscribe(d);
        执行到这里,fusionMode 为true
        if (d.fusionMode) {
            return;
        }

        d.run();
    }

执行到这里,fusionMode为true,程序也就执行完了。