rxjs switchMap 和 tap 问题

rxjs switchMap and tap issue

我正在使用 switchMap 运算符来清楚地了解 "switched" 内部可观察对象发生了什么。

起初我认为 switchMap 只是 "unsubscribing" 来自 switched inner observable,但后来我意识到它实际上是“unsubscribing AND completing” inner observable .

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

如你所见,finalize() operator 在 subject 第二次 emit 时被正确调用,但是:
为什么不调用 tap 运算符的完整处理程序

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

相关的不是那个:
我阅读并观看了许多有关 switchMap 的资源,包括:

其中 none 清楚地说明了内部可观察对象是取消订阅还是取消订阅并关闭(或者至少我不明白:))

我看了switchMap算子源码,没有提到takeXXX算子,没有那个他怎么完成内部算子?

tl;dr

我认为您混淆了 unsubscribe()complete() 之间的区别。对于像 Subject 这样的热门可观察对象,您可以通过几种方式 "stop" 它。从 'top->down' 和 complete() 就像你在你的例子中所做的那样,或者从 'bottom->up' 和 unsubscribe().

switchMap() 完全按照它说的去做,它从主要可观察对象切换到次要(或 'inner')可观察对象。这就是为什么当你 complete() 外部 observable 时,它​​对内部 observable 没有影响 - 链已被切换。要影响链(而不是仅仅影响作为源可观察对象的主题),您需要获得对订阅者的引用,然后调用该订阅者的 unsubscribe() 方法。

为了看到这个,我分叉了你的 CodeSandbox 并制作了这个 new one

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

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

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

希望这有助于稍微消除混乱。 :)