RxJava 深入分析

268 阅读2分钟

RxJava解决什么问题?

Rxjava 让程序员能够将任何耗时/异步的事件包装成为一个被观察者,通过rxJava的框架,传递给观察者,并在观察者中处理结果

期间能够自由的转换线程,并且具备对事件序列做任意变换。具体的能力描述如下:

  • 1.组装事件的能力 , 产生一个Observable , 例如create , from , map , flatMap等等
  • 2.发消息的能力Emitter,让使用者能够把传递事件到observer ,组装的事件能够顺利的达到任何一个观察者
  • 3.转换线程的能力,将耗时操作放到子线程
  • 4.事件组合的能力,例如多个事件的结果合并/有序发送
  • 5.链式调用,简化api,让代码符合逻辑

RxJava的主要组成部分?

  • Observable -- 事件源,被观察者
  • Observer -- 观察者,处理到来的事件
  • Emitter -- 事件发射器,提供给使用者发射事件的能力,内部持有observer对象

RxJava的执行流程?

rxJava的设计,采用双U型执行序解决多个操作符的叠加问题,先由源事件逐级向下构造新的事件源,然后逐级向上执行订阅,最后逐级向下执行onNext

U型流程图

rxjava常用操作符

创建操作符

create , just , from ,interval , range , repeat

变换操作符

map , flatmap,concatmap

flatmap 为什么会是无序的?

flatmap采用MergeObserver 继承了 AtomicInteger,所以这里的tryEmit方法就利用了 AtomicInteger 的同步机制,所以同时只会有一个 value 被 actual Observer 发射,而且这里 刚好 可以解答我们上面留下的 问题,由于 AtomicInteger CAS锁只能保证操作的原子性,并不保证锁的获取顺序,是抢占式的,所以最终数据的发射顺序并不是固定的(同一个Observable发出的数据是有序的)

concatmap 为什么是有序的?

concatmap 采用SourceObserver 同样继承了AtomicInteger,getAndIncrement方法保证自增的原子性,所以这里只有初始值为0时,执行下面的循环,进入循环,做了2个判断,一个是判断,是否已经disposed,如果是 清空队列并退出循环,还有个active字段,表示当前是否还有Observable在发射,(比如我们上面的例子,原始发射了5个数据,1,2,3,4,5,所以经过ConcatMap转换就有了5个 Observable,每个Observable各自携带3个数据,所以在这里如果用ConcatMap 操作符,这5个Observable都是严格排序发射,只有上一个发射完全完成之后,才会开始下一个,而且因为所有要发射的数据在之前已经加入到queue队列中,所以不曾在竞争,这样也就保证了数据发射的顺序)

过滤操作符

filter ,skip ,take ,ElementAt

合并操作符

zip , merge , concat , startWith

辅助操作符

observerOn , subscribeOn , doOnNext ,doOnSubscribe