可能比扔物线写得还好的对RxJava的理解

在看此文之前建议看下,https://www.jianshu.com/p/9ee9fa13eeef这篇文章,只有图,没有字

RxJava是什么

一个基于观察者模式的异步任务框架

好在哪?

好在用RxJava做的异步请求更简明更清晰
举例
需求:在IO线程上执行三个网络请求操作分别为query(A),query(B),query(C),且query(B)依赖于query(A)返回的结果,同样query(C)依赖于query(B)返回的结果

用android的异步框架得这么写(伪代码):

Server server = ...;
server.makeRequest(new Query('A'), new Listener(){
        onSuccess(boolean b){
            if(b){
                server.makeRequest(new new Query('B'), new Listener(){
                    onSuccess(boolean b){
                        if(b){
                            server.makeRequest(new Query('C'), new Listener(){
                                onSuccess(boolean b){
                                }
                            })
                        }
                    }
                })
            }   
       }

})

用Rxjava只需要这么写(伪代码)

Observable.just("A").flatMap((s) -> {
                return makeRequest(new Query(s));
        }).flatMap((aBoolean) -> {
            if(aBoolean) return makeRequest(new Query("B"));
            return null;
        }).flatMap((aBoolean) -> {
                if(aBoolean) return makeRequest(new Query("C"));
                return null;
        }).subscribeOn(Scheduals.io);
public static Observable<Boolean> makeRequest(Query query){
        return Observable.just(query)
                .map(new Function<Query, Boolean>() {
                    @Override
                    public Boolean apply(Query query) throws Exception {
                        //TODO
                        return true;
                    }
                });
    }

非常简洁,避免了回调地狱,之后会通过分析源码,去思考能够避免回调地狱的原因

准备知识
响应式编程

响应式编程是一种通过异步和数据流来构建事物关系的编程模型

数据流

是两个事物(在这里我们理解为函数)间关系的桥梁,且只有一个方向,即从上游实体到下游实体。举个例子f(x1)g(x2)之间如何产生关系?x1做为f的输入,当f(x1)生成后会通过数据(事件)流通知g(x2)执行,这里的f(x1)就是上游实体,g(x2)就是下游实体。但如果有这样的需求,三个独立的函数f(x1),f(x2),f(x3)都完成后再通知g(x2)?应该怎样去构建他们的关系?就是我们接下来要讲用异步的方式去构建

异步

数据流不能完全构建出函数之间的关系。如数据流一节所说f(x1),f(x2),f(x3)是相互独立的,他们之间的关系是独立的。这种独立的关系就可以用异步来表示。所以解决上一节的问题便是让f(x1),f(x2),f(x3)在各自的线程中执行,完成后再用数据流通知给g(x)

小结

异步是为区分无关的事物,数据流是为了联系起有关的事物。那么如何实现数据流传递呢?就用到下面的观察者模式

观察者模式

观察者模式面向的需求是:A对象对B对象的某种变化高度敏感,当B对象发生变化时,A对象需要瞬间做出反应,一般实现观察者模式需要有观察者Observer即A对象,有被观察者Observable即B对象,在实现的时候B对象需要持有A对象的引用,这样当B对象发生变化时,B对象才能通过A对象的引用让A对象做出反应,android中的典型实现便是监听器事件, View是被观察者,OnClickListener 是观察者用setOnClickListener(),让View持有OnClickListener的引用,当View监听到点击事件时便通知OnClickListener进行处理。这样子就简单的实现了数据流从B->A的传递。

解决问题的模型

RxJava可以通过很多操作符(就是RxJava中的一些方法)解决许多问题模型, 尽然它是异步任务框架,我们就来看看它是怎么处理异步任务问题模型的,只解释其中两种比较典型的问题模型。

map解决的模型

image.png

由模型图可知,首先我们需要创建可观测序列,然后再用观察者模式去通知它的下游实体map操作(其实模型中的虚线基本上是由观察者模式和异步实现的),在Map操作完成后形成了另一个可观测序列,在用观察者模式去通知这个序列依次输出。这样的模型可用来解决如下需求:子线程执行一个耗时任务,执行完成后返回给主线程

通过模型图可知,创建操作后需要通知变换操作,这个通知就用观察者模式实现。而变换操作是独立的而且在子线程,所以需要通过异步来实现,且变换操作执行完成后要通知给主线程的。所以也要使用观察者模式

创建操作

如前文所述,创建操作可以看做是一个函数f(x),由于f(x)要通知下游的,所以这里的f(x)是被观察者,在RxJava里用Observable表示被观察者去发起通知。在RxJava中f为just,假设这里的输入x为”A”,所以其创建操作为Observable.just('A').

变换操作 f

同理这里的变换操作为map,需要运行在子线程,要用Handler实现。

通知操作

而子线程的通知操作也要用观察者模式实现,其需要引用一个观察者,这个观察者需要自己定义,也就是说某个耗时的转换操作在子线程运行完成后,要发送到你自己定义的主线程的观察者中

flatMap解决模型

flatmap分析.png

从模型图我们可以看到,FlatMap里面的数据有两个特点:
- 数据被分成了n个
- 这n个数据也在可观测的序列上
对应的 ,它能解决两个基本需求:
- 原始的单个数据是集合类,比如List<String>FlatMap可以把它们变成一个个String.
- 这每个String都在可观测序列上,所以也能有通知操作的能力
所以对于第一点他能够简单遍历二维数据,举个例子:需求是遍历所有学生选的课程

final List<Student> list = ...
 Disposable disposable = Observable.fromIterable(list)
                /*将学生的课程发送出去,从学生实例得到课程实例,再发射出去*/
                .flatMap(new Function<Student, ObservableSource<Student.Course>>() {
  @Override
public ObservableSource<Student.Course> apply(S
  • 2
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值