RxJava 中observer链是如何形成的?

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/ameryzhu/article/details/83929986

接着上一篇博客继续分析。

Observable.create(new ObservableOnSubscribe<String>() {
            @Override
            public void subscribe(ObservableEmitter<String> emitter) throws Exception {
                emitter.onNext("hello");
            }
        }).map(new Function<String, String>() {
            @Override
            public String apply(String s) throws Exception {
                return "abc-"+s;
            }
        }).map(new Function<String, String>() {
            @Override
            public String apply(String s) throws Exception {
                return s+"-def";
            }
        }).subscribe(new Consumer<String>() {
            @Override
            public void accept(String s) throws Exception {
                System.out.println("result:"+s);
            }
        });

我们来看看添加了map操作后的subscribe有些什么变化?

public final class ObservableMap<T, U> extends AbstractObservableWithUpstream<T, U> {
    final Function<? super T, ? extends U> function;

    public ObservableMap(ObservableSource<T> source, Function<? super T, ? extends U> function) {
        super(source);
        this.function = function;
    }

    @Override
    public void subscribeActual(Observer<? super U> t) {
        source.subscribe(new MapObserver<T, U>(t, function));
    }
...

当我们到达最后一个observable的时候,它是一个ObservableMap类型的Observable,因为AbstractObservableWithUpstream类继承了Observable类。

abstract class AbstractObservableWithUpstream<T, U> extends Observable<U> implements HasUpstreamObservableSource<T> {

我们调用subscribe方法,最后都会调用到Observable抽象类子类的实现方法subscribeActual();我们来重点关注下,它做了些什么。它与最开头的ObservableCreate方法中的subscribeActual()有啥不同的。

可以看到ObservableMap中的subscribeActual()方法把调用交给了source.subscribe()方法,而source是什么?在上篇文章中分析了,是当前observable实例,也是链式的upstream上个节点。也就说交给了第一个ObservableMap的subscribe()方法,

怎么闻到了一丝递归调用的味道?

这里通过不断调用 [上个Observable].subscribe()找到第一个节点,也就是我们通过Observable.create()构造的observable,来看看这个类的subscribeActual()

public final class ObservableCreate<T> extends Observable<T> {
    final ObservableOnSubscribe<T> source;

    public ObservableCreate(ObservableOnSubscribe<T> source) {
        this.source = source;
    }

    @Override
    protected void subscribeActual(Observer<? super T> observer) {
        CreateEmitter<T> parent = new CreateEmitter<T>(observer);
        observer.onSubscribe(parent);

        try {
            source.subscribe(parent);
        } catch (Throwable ex) {
            Exceptions.throwIfFatal(ex);
            parent.onError(ex);
        }
    }

虽然这个类中也看到了类似source.subscribe()方法,但是这里的source已经没有更早的节点了。所以也就是我们传入的ObservableOnSubscribe接口的实现类。

总结一下:在observable链中,subscribe()方法会一直递归,追溯到最原始的起点处,然后再调用其subscribe()方法。

其实知道这一点对于subscribeOn()的线程切换就可以了解到一点了。这个后续写线程切换原理系列再来讨论。

接着,我们分析一下Observer链是怎么形成的?

我们先看一下每加入一个map操作符,observer的构造发生了怎样的变化。先看第一个map的操作符的subscribeActual()方法。

public void subscribeActual(Observer<? super U> t) {
        source.subscribe(new MapObserver<T, U>(t, function));
    }

这里把之前从Consumer创建的LambdaObserver传进来,作为构造函数的参数传给了MapObserver,并传给了父类的构造函数。

static final class MapObserver<T, U> extends BasicFuseableObserver<T, U> {
        final Function<? super T, ? extends U> mapper;

        MapObserver(Observer<? super U> actual, Function<? super T, ? extends U> mapper) {
            super(actual);
            this.mapper = mapper;
        }

        @Override
        public void onNext(T t) {
            ...
            downstream.onNext(v);
        }
        ...
    }

MapObserver继承的BasicFuseableObserver也继承于Observer,lambdaObserver赋值给了downStream对象。

public abstract class BasicFuseableObserver<T, R> implements Observer<T>, QueueDisposable<R> {

    /** The downstream subscriber. */
    protected final Observer<? super R> downstream;

    ...
    public BasicFuseableObserver(Observer<? super R> downstream) {
        this.downstream = downstream;
    }
    ...
}

可以看到MapObserver在OnNext()方法中,最终又调用了downstream的onNext()方法,MapObserver,LambdaObserver都继承于Observer,这里很明显,对方法进行了增强,同时又持有了当前的Observer作为下一个被调用的节点。既使用到了装饰者模式,又是一种责任链。当最上层的emitter吐数据的时候,优先调用了当前Observer的onNext(),等到执行完后,再开始调用下一个Observer的onNext(),这样达到了层层传递,层层处理的目的。

我们还可以继续看一下其它操作符,他们是不是也是类似的一套流程:

看看FlatMap的:

public final class ObservableFlatMap<T, U> extends AbstractObservableWithUpstream<T, U> {
    ...
    public ObservableFlatMap(ObservableSource<T> source,
            Function<? super T, ? extends ObservableSource<? extends U>> mapper,
            boolean delayErrors, int maxConcurrency, int bufferSize) {
        super(source);
        ...
    }

    @Override
    public void subscribeActual(Observer<? super U> t) {
        ...
        source.subscribe(new MergeObserver<T, U>(t, mapper, delayErrors, maxConcurrency, bufferSize));
    }

    static final class MergeObserver<T, U> extends AtomicInteger implements Disposable, Observer<T> {

        
        final Observer<? super U> downstream;
        ...

        MergeObserver(Observer<? super U> actual, Function<? super T, ? extends ObservableSource<? extends U>> mapper,
                boolean delayErrors, int maxConcurrency, int bufferSize) {
           ...
        }

        ...
        @Override
        public void onNext(T t) {
            ...
            subscribeInner(p);
        }

        void subscribeInner(ObservableSource<? extends U> p) {
            ...
                    if (tryEmitScalar(((Callable<? extends U>)p)) && maxConcurrency != Integer.MAX_VALUE) {
                       ...
                } ...
            }
        }

        ...

boolean tryEmitScalar(Callable<? extends U> value) {
            ...

            if (get() == 0 && compareAndSet(0, 1)) {
                downstream.onNext(u);
               ...
            } else {
                ...
        }
}

其中省掉了很多无关分析的代码,首先subscribeActual()的时候一样会对上一个observable进行追溯。

在构造Observer的时候呢,一样采用装饰者模式把当前节点作为下一个节点添加到新的Observer中。

MergeObserver的onNext方法中一样是先执行自己的内容,最后又通过两层调用,回到了downStream下游节点这个Observer的onNext()方法。可见套路非常类似。有点像ViewGroup事件拦截的冒泡方式,只不过刚好相反,这个先浮上来,再沉下去。

在subscribe()逆向执行的过程中,也形成了一条正向Observer链条,这样当追根溯源到起始的Emitter开始吐数据时,后面的onNext都按照责任链,一步一步走下去。

一旦明白了observable与observer这两条链路关系后,RxJava的框架就比较清晰了,线程切换原理更容易理解。因为observeOn(),subscribeOn()也被封装成了类似的一套处理流程。后面再写文章来分析一下。

猜你喜欢

转载自blog.csdn.net/ameryzhu/article/details/83929986