一个例子理解Rxjava的事件流转换原理

本文使用Rxjava1.0实例,重在研究思想和原理。

以map操作符为例:

        Observable> observable =  Observable.create(new Observable.OnSubscribe>() {
                @Override
                public void call(Subscribersuper HttpResult> subscriber) {
                }
            });
        observable.map(new Func1, Object>() {
            @Override
            public Object call(HttpResult objectHttpResult) {
                return objectHttpResult.data;
            }
        })
        .subscribe(subscriber); 
  

几个相关类的理解:

func1:

public interface Func1<T, R> extends Function {
        R call(T t);
    }

func1 《T,R》 的工作就是T-》R的转换;
Operator

public interface Operator<R, T> extends Func1<Subscribersuper R>, Subscribersuper T>> {
        // cover for generics insanity
    }

Operator 是Func1的子类,做的工作是把一个Subscriber R转化成另外一个Subscriber T。
Observer:

public interface Observer {

        /**
         * Notifies the Observer that the {@link Observable} has finished sending push-based notifications.
         * 

* The {@link Observable} will not call this method if it calls {@link #onError}. */ void onCompleted(); /** * Notifies the Observer that the {@link Observable} has experienced an error condition. *

* If the {@link Observable} calls this method, it will not thereafter call {@link #onNext} or * {@link #onCompleted}. * * @param e * the exception encountered by the Observable */ void onError(Throwable e); /** * Provides the Observer with a new item to observe. *

* The {@link Observable} may call this method 0 or more times. *

* The {@code Observable} will not call this method again after it calls either {@link #onCompleted} or * {@link #onError}. * * @param t * the item emitted by the Observable */ void onNext(T t);

观察者类,回调给观察者。
Subscriber:

public abstract class Subscriber implements Observer, Subscription

Subscription :

public interface Subscription {

        /**
         * Stops the receipt of notifications on the {@link Subscriber} that was registered when this Subscription
         * was received.
         * 

* This allows unregistering an {@link Subscriber} before it has finished receiving all events (i.e. before * onCompleted is called). */ void unsubscribe(); /** * Indicates whether this {@code Subscription} is currently unsubscribed. * * @return {@code true} if this {@code Subscription} is currently unsubscribed, {@code false} otherwise */ boolean isUnsubscribed(); }

很明显,是Observer类的扩充,加了Subscription的解订阅能力。

map操作的具体过程:

public final  Observable map(Func1super T, ? extends R> func) {
            return lift(new OperatorMap(func));
        }

关键在lift:

public final  Observable lift(final Operatorsuper T> operator) {
            return **1**new Observable(**2**new OnSubscribe() {
                @Override
                public void call(Subscribersuper R> o) {
                    try {
                        **3**Subscribersuper T> st = hook.onLift(operator).call(o);
                        try {
                            // new Subscriber created and being subscribed with so 'onStart' it
                            **4**st.onStart();
                            **5**onSubscribe.call(st);
                        } catch (Throwable e) {
                            // localized capture of errors rather than it skipping all operators 
                            // and ending up in the try/catch of the subscribe method which then
                            // prevents onErrorResumeNext and other similar approaches to error handling
                            Exceptions.throwIfFatal(e);
                            st.onError(e);
                        }
                    } catch (Throwable e) {
                        Exceptions.throwIfFatal(e);
                        // if the lift function failed all we can do is pass the error to the final Subscriber
                        // as we don't have the operator available to us
                        o.onError(e);
                    }
                }
            });
        }

OnSubscribe

public interface OnSubscribe<T> extends Action1<Subscribersuper T>> {
            // cover for generics insanity
        }

OnSubscribe 做的事,就是拿到Subscriber,开始发送流程。
分析下
看1,原来并没有用原来的Observable,而是新new了一个;
2,new的Observable没有用之前的OnSubscribe,也是new 了一个,这个OnSubscribe 后面会在subscribe调用的时候使用;
3,hook.lift;hook这里是个默认实现,返回的结果仍是operator,然后调用operator.call(o),这个o是OnSubscribe.call调用的时候传过来的,上面说了,operator做的事,就是把一个Subscriber转成另一个Subscriber。
看下Map操作的operator,OperatorMap的实现:

public final class OperatorMap<T, R> implements Operator<R, T> {

        private final Func1super T, ? extends R> transformer;

        public OperatorMap(Func1super T, ? extends R> transformer) {
            this.transformer = transformer;
        }

        @Override
        public Subscribersuper T> call(final Subscribersuper R> o) {
            return new Subscriber(o) {

                @Override
                public void onCompleted() {
                    o.onCompleted();
                }

                @Override
                public void onError(Throwable e) {
                    o.onError(e);
                }

                @Override
                public void onNext(T t) {
                    try {
                        o.onNext(transformer.call(t));
                    } catch (Throwable e) {
                        Exceptions.throwOrReport(e, this, t);
                    }
                }

            };
        }

    }

operator做的事,就是把一个Subscriber转成另一个Subscriber,没毛病,OperatorMap把构造函数依赖的Fucn1用在了从Subscriber o 到 返回的Subscriber 的转换关系中,在这个时候,新的Subscriber o.next(T t)中回调的t是被func1定义转换规则的、转换后的新对象。在这一步就完成了转换。
回过头来看3,其实hook.onLift(operator).call(o)返回的就已经是转换过的Subscriber;
4、转换过的Subscriber.onStart();
5、之前Observable创建的OnSubscribe 执行事件流。这个地方,新的Observable新的OnSubscribe确用了之前的OnSubscribe,也就是说,转换之后的Subscriber传递到了上层。伪代码如下;

new Observable(onSubscribe){
        OnSubscribe old = onSubscribe;
        lift(){
            new Observable(new OnSubscribe{
                call(subscriber){
                    //doSomeThing...例如通过Opertor转换成新的subscriber 起个名叫newSubscriber
                    old.call(newSubscriber);
                    //doSomeThing...
                }
            }//这个new的OnSubscribe 起个名叫onSubscribe1){
                    OnSubscribe old1= onSubscribe1;
                        lift(){
                            //...一直重复
                        }
                    }
        }
    }

所以调用n次lift,就会有n个Observable,n个OnSubscribe,n次转换,下一层会持有上一层的OnSubscribe引用,在每一层的call方法中装饰上一层(old)OnSubscribe,装饰的过程是用operator对subscriber进行转换subscriber(newSubscriber),会通过上一层(old)OnSubscribe的call方法传给上一个(old)Observable
,一直递归上去直到最开始的OnSubscribe,也就是我们的事件开始流。
再看下subscribe的动作。

private static  Subscription subscribe(Subscribersuper T> subscriber, Observable observable) {
     // validate and proceed
        if (subscriber == null) {
            throw new IllegalArgumentException("observer can not be null");
        }
        if (observable.onSubscribe == null) {
            throw new IllegalStateException("onSubscribe function can not be null.");
            /*
             * the subscribe function can also be overridden but generally that's not the appropriate approach
             * so I won't mention that in the exception
             */
        }

        // new Subscriber so onStart it
        subscriber.onStart();

        /*
         * See https://github.com/ReactiveX/RxJava/issues/216 for discussion on "Guideline 6.4: Protect calls
         * to user code from within an Observer"
         */
        // if not already wrapped
        if (!(subscriber instanceof SafeSubscriber)) {
            // assign to `observer` so we return the protected version
            subscriber = new SafeSubscriber(subscriber);
        }

        // The code below is exactly the same an unsafeSubscribe but not used because it would 
        // add a significant depth to already huge call stacks.
        try {
            // allow the hook to intercept and/or decorate
            **6**hook.onSubscribeStart(observable, observable.onSubscribe).call(subscriber);
            return hook.onSubscribeReturn(subscriber);
        } catch (Throwable e) {
            // special handling for certain Throwable/Error/Exception types
            Exceptions.throwIfFatal(e);
            // if an unhandled error occurs executing the onSubscribe we will propagate it
            try {
                subscriber.onError(hook.onSubscribeError(e));
            } catch (Throwable e2) {
                Exceptions.throwIfFatal(e2);
                // if this happens it means the onError itself failed (perhaps an invalid function implementation)
                // so we are unable to propagate the error correctly and will just throw
                RuntimeException r = new RuntimeException("Error occurred attempting to subscribe [" + e.getMessage() + "] and then again while trying to pass to onError.", e2);
                // TODO could the hook be the cause of the error in the on error handling.
                hook.onSubscribeError(r);
                // TODO why aren't we throwing the hook's return value.
                throw r;
            }
            return Subscriptions.unsubscribed();
        }
    }

这个代码看起来有点多,其实是纸老虎。
先看入参:subscriber,就是我们自己接收回调的subscriber;observable传的是this,也就是调用subscribe方法的observable,如上面所说,每次lift之后都是一个新的Observable、新的OnSubscribe。
再看6,hook.onSubscribeStart(observable, observable.onSubscribe).call(subscriber) 的默认实现最后还是走了
observable.onSubscribe.call(subscriber);这个时候就回到了lift里面的3,也就是说,这个subscriber 就是lift中的o(old subscriber),在call中,被operatormap 通过Func1装饰成了st。而在lift操作中的onSubscribe.call中,新的onSubscribe开始事件流。

再理一下过程:
1、当我们使用Observable 的subcribe方法的时候,会传一个接收回调的(下游)subscriber o;
2、Observable 会调用用它的成员OnSubscribe 的call方法;
3、这个call方法,其实就是在map操作时lift new 的OnSubscribe的call方法,也就是说这个new出来的OnSubscribe就是2中使用的;
4、call方法中,把subscriber o 通过operatorMap中的func1转成了subscriber st;
5、用上一层的OnSubscribe继续调用call(丢给上游装饰),再此转化,直至到最顶层。

至此,完成了上下游的切换。简单总结,就是从下游开始,每次lift都在不断装饰,直到丢给最上层的用来发送事件流的OnSubscribe是完成所有转换规则的OnSubscribe。
总结一下这个过程的设计模式,上面提到了多次“装饰”,没错,很多地方都是用装饰者模式装饰,也就是所谓的转换操作;然后lift一层一层装饰处理,中间甚至可以拦截,整体思想有点类似责任链。

你可能感兴趣的:(android,java)