RXJava map方法分析

此篇文章分析RXjava中的lift方法(Observable类中)


首先,先分析较为简单的map方法,分析下面这段代码:

ServerAPI.getAPIClient().getYachtIndex().map(new Func1<TMResponse<YachtIndexBean>, YachtIndexBean>() {
            @Override
            public YachtIndexBean call(TMResponse<YachtIndexBean> yachtIndexBeanTMResponse) {
                return yachtIndexBeanTMResponse.getData();
            }
        });

其中:

 public interface TMGolfAPI {

        @GET("/index.php?r=api/yachtSiteIndex")
        Observable<TMResponse<YachtIndexBean>> getYachtIndex();
    }

调用map 方法时,直接进入

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

PS一句:
大家都知道
Func1接口中泛型是T是指输入类型,R输出类型,暂这么理解吧。

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

那么看到,map()方法中的Fun1又对参数做了限定。<? super T, ? extends R>
这里有一个比较重要的概念,即:
super泛型中用于对参数类型的限定,不能对返回类型做限定
extendse于对返回类型的限定, 不能对参数类型做限定。
栗子可以看我转载的另一篇文章: Java 泛型


咳咳,继续。
map 方法直接返回return lift(new OperatorMap<T, R>(func));
再进去看一下OperatorMap类。OperatorMap<T, R> implements Operator<R, T> ,OperatorMap又继承了Operator。Operator又是Func1的子类。

  */
    public interface Operator<R, T> extends Func1<Subscriber<? super R>, Subscriber<? super T>> {
        // cover for generics insanity
    }

那么先记住,*OperatorMap 就是一个Func1接口的实现。且输入和输出都是一个Subscriber();*

重点:public final class OperatorMap<T, R> implements Operator<R, T>
它在类声名的时候,直接把参数调换了。

那么回调方法中,OperatorMap.call()返回了一个Subscriber,类型是原有的类型:

 @Override
    public Subscriber<? super T> call(final Subscriber<? super R> o) {
        return new Subscriber<T>(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);
                }
            }

        };
    }

注意:* o.onNext(transformer.call(t));* 这里的o指是的最终转换完成,observable 被订阅的subscriber。

接下来重点分析 lift

  public final <R> Observable<R> lift(final Operator<? extends R, ? super T> operator) {
        return new Observable<R>(new OnSubscribe<R>() {
            @Override
            public void call(Subscriber<? super R> o) {
                try {
                    Subscriber<? super T> st = hook.onLift(operator).call(o);
                    try {
                        // new Subscriber created and being subscribed with so 'onStart' it
                        st.onStart();
                        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);
                }
            }
        });
    }

最终要返回的是一个Observable 对象,实际上,这里调用了lift方法,都是重建一个Observable,所以的操作都会在这个Observable的call方法中进行转换,这里直接new 了一个。
它的call方法中。

  Subscriber<? super T> st = hook.onLift(operator).call(o);

那么这个hook指的是最外层的observable 也就是Observable<TMResponse<YachtIndexBean>>

hook.onLift(operator)

直接返回,operator。(理解成直接operator.call(o));

  public <T, R> Operator<? extends R, ? super T> onLift(final Operator<? extends R, ? super T> lift) {
        return lift;
    }

返回了OperatorMap中的Subscriber<? super T>。


到这里, 其实思路非常的清晰了。我们再来理一理:
首先:1. ServerAPI.getAPIClient().getYachtIndex();返回Observable ,我们暂叫Observable 1.
调用Observable.map();时,map方法会创建一个新Observable。在我们subscribe订阅的时候。立即执行 里面的call 方法。

@Override
            public void call(Subscriber<? super R> o) {
                try {
                    Subscriber<? super T> st = hook.onLift(operator).call(o);
                    try {
                        // new Subscriber created and being subscribed with so 'onStart' it
                        st.onStart();
                        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);
                }
            }

然后调用operator.call(); 并把Subscriber传进去。
operator).call()方法中,做了一个代理。
operator里面返回的Subscriber 的onNext 会调用最终的Subscriber.onNext();

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

返回的Subscriber这时并不会执行,因为它的call方法还没被调用。最后再用最初的Observable 1去调用。onSubscribe.call(st)。

如此一来, map()就发挥中间数据转换的作用。并且参数已经由神奇的泛型帮我们处理好了。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值