深入理解RxJava的lift变换

作者: javalong | 来源:发表于2018-05-04 19:45 被阅读60次
    前言

    因为这些时间我一直在写RxJava操作符源码解析,每次讲到一些操作符的时候,就不免要涉及到了lift变换。所以这里我单独拿出来讲解一下,希望能对大家有帮助。

    正文

    给 Android 开发者的 RxJava 详解

    一般学了 RxJava的人都会看这篇文章,图文并茂,写的很好。

    其中就介绍到了lift。归纳的也比较好。其中一段代码是这样的。

    // 注意:这不是 lift() 的源码,而是将源码中与性能、兼容性、扩展性有关的代码剔除后的核心代码。
    // 如果需要看源码,可以去 RxJava 的 GitHub 仓库下载。
    public <R> Observable<R> lift(Operator<? extends R, ? super T> operator) {
        return Observable.create(new OnSubscribe<R>() {
            @Override
            public void call(Subscriber subscriber) {
                Subscriber newSubscriber = operator.call(subscriber);
                newSubscriber.onStart();
                onSubscribe.call(newSubscriber);
            }
        });
    }
    

    虽然不是lift源码,但是作用是一样的,比源码更容易懂。
    这里涉及到到create,大家可以看下我的这篇文章我是最简单的操作符-----Create

    下面我们来分析上面的这段代码。主要做了什么事情呢。

    我们一句一句来分析

    1. Observable.create
      lift方法调用后最终返回的其实还是一个Observable对象。
    2. observable.subscribe 这一句代码没有,但是连起来看,会更顺畅
      Observable对象最终肯定会调用subscribe方法。在这篇文章我是最简单的操作符-----Create中已经有介绍,observable.subscribe最后,其实就是observable.onSubscribe.call(subscriber)

    重点来了----->

    这里的subscriber调用observable.subscribe传入的参数。也就是我们自己的onNext,onError,onComplete这几个抽象方法的一个实现的对象。

    这里的observable.onSubscribe是 代码

    new OnSubscribe<R>() {
            @Override
            public void call(Subscriber subscriber) {
                Subscriber newSubscriber = operator.call(subscriber);
                newSubscriber.onStart();
                onSubscribe.call(newSubscriber);
            }
        }
    

    创建的OnSubscribe对象。

    所以observable.onSubscribe.call(subscriber)其实就是直接调用了上面的这段代码的call方法。

    call方法一共3行,我们一看就知道哪句是最重要的。

    Subscriber newSubscriber = operator.call(subscriber);
    这一句是关键,为什么要叫lift,其实就是要把一个Subscriber变换为另外一个Subscriberlift方法需要传入一个Operator对象,而Operator对象就是如何把Subscriber变换为另外一个Subscriber的具体实现。

    那么我们来选取一个简单的Operator接口实现来看一下。大家可以看一下这篇文章我是用来组合的操作符------Buffer,里面就有一个具体的Operator实现。没看过的朋友可以简单看一下,了解一下。

    public final class OperatorBufferWithSize<T> implements Operator<List<T>, T>
    

    OperatorBufferWithSize的作用就是把List<T>类型的Subscriber转化为了T类型的Subscriber。至于为什么OperatorBufferWithSize的作用不是把T类型的Subscriber转化为List<T>类型的Subscriber,在我是用来组合的操作符------Buffer这篇文章中也有所介绍。

    由于我们的正常的思维一直是从上至下,所以这里可能理解起来会有点难度。
    给 Android 开发者的 RxJava 详解
    这篇文章中有一张图片

    image.png

    当我们使用链式结构,使用了很多操作符的时候,其实会创建很多的Observable对象。但是我们使用的其实是最后一个创建的Observable

    很明显,我们是从最后一个Observable开始运行,然后一步步往上调用,其实这里调用的是当前对应的observable.onSubscribe.call(subscriber),当然这里的3个对象observableonSubscribesubscriber都是不停在变化的,有点递归的意思。我们只需要先知道,从下往上,调用的是onSubscribe对象的call方法。到达最顶部的一个ObservableonSubscribecall方法执行后,就一步步往下调用subscriberonNext方法。

    lift的作用就是在一步步往上调用call方法的使用改变Subscriber对象。
    这样我们就能够理解OperatorBufferWithSize的作用就是把List<T>类型的Subscriber转化为了T类型的Subscriber

    总结:lift的作用:在链式结构中,从下往上看,把下面的类型的Subscriber转化为了上面类型的Subscriber。(结合上下文来理解这句话)

    相关文章

      网友评论

        本文标题:深入理解RxJava的lift变换

        本文链接:https://www.haomeiwen.com/subject/iehjrftx.html