一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第8天,点击查看活动详情。
之前我们介绍了RxSwift中的一些高阶函数,这篇文章主要介绍下组合操作符的原理,组合操作符,通常就是把我们需要源序列合成一个新的序列交由订阅者订阅,通常会有startWith,merge,zip,combineLatest等之前的使用中也有介绍,这里介绍其中的一种其他的类似
1. zip
可以看到最多可以合成
8个源序列,这里主要介绍2个。
- 初始化
让我们传入2个源序列,根据2个源序列的Element生成一个新的Element
- zip2
初始化的时候会保存我们2个源序列和我们生成resultSelector的闭包,zip2继承Producer因此在订阅的时候会走subscribe->子类的run 因此我们继续看下sink
- ZipSink2_
我们先看初始化的时候会传入parent,调用ZipSink的初始化,其中对应的values1是一个Sequence类型的数组长度为2也就是可以存储对应源序列发送的element
这里就是核心,在初始化的时候传入我们的序列源,其中isDone数组表示序列源是否都发送了信号,默认不发送。当进行next的时候,判断当前的数组是否都是true也就是都有信号。有的话调用我们的观察者闭包。
- run
我们看下
run方法是怎么关联他们的关系的
SingleAssignmentDisposable可以理解为单一工作,disposeable一种,用来销毁我们的序列。继续看ZipObserver这里初始化的时候会添加一把锁和我们的parent也就是自身(保护源序列1和源序列2)位置,以及我们发送初始化的值
- ZipObserver
遵循我们ObserverType协议因此可以实现on方法,在on方法中会实现synchronizedOn方法,判断当前的parent是否为nil,不为nil处理error和complete的事件。如果是存在parent,如果.next调用我们的源序列的中事件。否则处理我们parent的error和complete的事件。
- subscribe
source1.subscribe(observer1)和source2.subscribe(observer2)订阅观察者,这样当我们的其中的一个订阅者发送onNext事件就会进入parent.next(self.index)
之后进入ZipSink的next方法,就如我们之前分析的2个序列源都发送信号才会进入ZipObserver观察者回调方法。
流程大概就是下面
2. combineLatest
combineLatest 和zip类似,我们看下初始化
- combineLatest2
初始化的时候保存我们源序列,并保存我们生成的element闭包。订阅的时候会调用run方法
- CombineLatestSink2_
和我们的zipSkin2_类似,我们继续看下
- CombineLatestObserver
订阅进入on方法,和上面的ZipObserver类似,都是在next事件下先调用自身源序列自身订阅者的事件回调,之后调用组合订阅者回调。
1.3 merge
- merge
会把我们外面合并的序列源订阅数组当成一个新的源序列,里面的元素element就是序列
3. 总结
对于组合操作符本质通过数组保存各个序列发送的状态,从而根据这些状态和发送的信号值进行判断是否发送组合的订阅事件。