1

我正在玩 switchMap 运算符,以清楚地了解“切换”的内部可观察对象发生了什么。

起初我认为 switchMap 只是从切换的内部 observable 中“取消订阅”,但后来我意识到它实际上是“取消订阅并完成”内部 observable。

为了确认我已经写了这个小片段: https ://codesandbox.io/s/relaxed-meninsky-c5jmw?fontsize=14

如您所见,在主题第二次发出时正确调用了finalize()运算符,但是:
为什么不调用tap运算符的完整处理程序

不知何故,我对这个运算符的理解只有 80% 感到满意。

与此无关:
我已阅读并观看了有关 switchMap 的大量资料,包括:

而且他们都没有明确说明内部可观察对象是否已取消订阅或取消订阅并已关闭(或者至少我不明白:))

我看过switchMap算子源码,没有提到takeXXX算子,没有那个怎么能完成内层算子呢?

tl;博士

  • 您是否确认 switchMap 在切换时完成了内部可观察?
  • 为什么水龙头操作员不能按预期工作?
  • 如果 switchMap 有效地完成了内部 observable,他怎么能在内部不使用 takeXXX 运算符的情况下做到这一点?
4

1 回答 1

2

unsubscribe()我认为您混淆了和之间的区别complete()。对于像 a 这样的热可观察对象,Subject您可以通过几种方式“停止”它。像您在示例中所做的那样从“自上而下”complete()或从“自下而上”使用unsubscribe().

switchMap()正如它所说的那样,它从主要的可观察对象切换到次要(或“内部”)可观察对象。这就是为什么当你complete()使用外部 observable 时,它​​对内部 observable 没有影响 - 链已被切换。要影响链(而不是仅仅影响作为源 observable 的 Subject),您需要获取对订阅者的引用,然后调用订阅者的unsubscribe()方法。

为了看到这一点,我已经分叉了你的 CodeSandbox 并制作了这个新的

正如您将在该 CodeSandbox 中看到的那样,我添加了几行以显示正在发生的事情:

  • 请注意tap()switchMap 正上方的链中的新内容 - 这将显示在Subject()使用 switchMap 运算符将链切换到不同的 Observable 之前直接发生的事情。
  • 链的订阅现在被捕获在变量sub中,以后可以取消订阅以从下到上影响链。
  • 请注意,s.complete()10 秒后的时间现在反映在主题中,还要注意它根本不会影响链条。
  • 现在请注意,新的sub.unsubscribe()15 秒后确实会杀死链条。
  • 取消注释方法take(5)中的注释newT()以查看如果上面的源实际完成(自上而下),则确实会调用点击的完整方法。

finalize()捕捉到取消订阅已经发生的事实(底部->向上),请注意,当在主题源上调用switchMap()自动向上取消订阅时s.next(),以及在unsubscribe()订阅上调用时,它都会发生,这再次导致底部- >向上终止。在任何情况下都不会complete()调用原始观察者,因为链从未真正完成。如果需要,您可以与操作员一起完成链take(10),看看它是如何工作的。

希望这有助于消除一些混乱。:)

于 2019-08-29T01:06:20.280 回答