上一节我们学习了mergeMap的相关知识,我们知道了在并发执行的时候,我们可以使用mergeMap来达到效果。今天我们学习另一个高阶运算符switchMap。
同样的道理,我们想要学习理解switchMap,我们首先得知道什么是switch?
Observable Switching
switch的概念更接近于merging而不是concatenation,因为我们不等待任何 Observable 终止。但是在switching时,与concatenation不同,如果一个新的 Observable 开始发出值,我们将在订阅新的 Observable ,取消订阅之前的 Observable。
Observable switching就是确保未使用的 Observable 的退订逻辑被触发,从而释放资源!
Switch弹珠图
注意对角线,这些不是偶然的!在切换策略的情况下,在图中表示高阶 Observable 很重要,它是图像的顶线。这个高阶 Observable 发出本身就是 Observable 的值。对角线从高阶 Observable 顶线分叉的时刻,是 Observable 值被发出并通过 switch 订阅的时刻。
分解弹珠图
1、高阶 Observable 发出它的第一个内部 Observable (a-b-c-d),它被订阅(通过 switch 策略实现)
2、第一个内部 Observable (a-b-c-d) 发出值 a 和 b,它们会立即反映在输出中
3、但是随后第二个内部 Observable (e-f-g) 被发出,这触发了从第一个内部 Observable (a-b-c-d) 的取消订阅,这是切换的关键部分
4、然后第二个内部 Observable (e-f-g) 开始发出新值,这些值反映在输出中
5、但请注意,第一个内部 Observable (a-b-c-d) 同时仍在发出新值 c 和 d
6、然而,这些后来的值并没有反映在输出中,那是因为我们同时取消了第一个内部 Observable (a-b-c-d) 的订阅
我们现在可以理解为什么必须以这种不寻常的方式绘制图表,使用对角线:这是因为我们需要直观地表示每个内部 Observable 何时被订阅(或取消订阅),这发生在对角线从源高阶 Observable 分叉的点处。
好了,理解了switch的原理,我们现在可以来看看switchMap。
SwitchMap操作符
假设我们有一个普通的输入流,它发出值 1、3 和 5。然后我们将每个值映射到一个 Observable,就像我们在 concatMap 和 mergeMap 的情况下所做的那样,并获得一个更高阶的 Observable。如果我们现在在发出的内部 Observable 之间切换,而不是连接它们或合并它们,我们最终得到 switchMap 运算符:
switchMap弹珠图
弹珠图分解
1、源 observable 发出值 1、3 和 5
2、然后通过映射函数将这些值转换为 Observables
3、映射的内部 Observable 被 switchMap 订阅
4、当内部 Observable 发出一个值时,该值会立即反映在输出中
5、但是如果在前一个 Observable 有机会完成之前发出了一个像 5 这样的新值,则前一个内部 Observable (30-30-30) 将被取消订阅,并且它的值将不再反映在输出中
6、注意上图中红色的 30-30-30 内部 Observable:最后的 30 值没有发出,因为 30-30-30 内部 Observable 被取消订阅
正如我们所见,Observable 切换就是确保我们从未使用的 Observable 中触发取消订阅逻辑。现在让我们看看 switchMap 的实际效果!