我正在与switchMap运算符一起玩耍,以清楚地了解“可切换”内部可观察到的情况。
起初,我认为switchMap只是从切换后的内部可观察对象中“取消订阅”,但后来我意识到实际上是“ 取消订阅并完成”内部可观察对象。
要确认我已经写了这个小片段: https://codesandbox.io/s/relaxed-meninsky-c5jmw?fontsize=14
如您所见,当对象第二次发射时,会正确调用 finalize()运算符,但是:
为什么不调用tap操作符的完整处理程序?
以某种方式,我对这个操作员的理解使80%的人感到满意。
与此无关的相关内容:
我已经阅读并观看了有关switchMap的大量资源,包括:
并且它们都没有明确说明内部可观察项是否已取消订阅或未订阅并已关闭(或者至少我不理解它:))
我已经看过switchMap运算符的源代码,并且没有提到 takeXXX 运算符,如果没有该操作符,他如何完成内部运算符?
tl; dr
答案 0 :(得分:1)
我认为您正在混淆unsubscribe()
和complete()
之间的区别。对于像Subject
这样的热点,您可以通过几种方式“停止”它。就像在示例中一样,使用complete()
从'top-> down',或者使用unsubscribe()
从'bottom-> up'。
switchMap()
完全按照其说的去做,它从主要的可观察的切换到次要的(或“内部”)观察。这就是为什么当您complete()
外在可观察物对内在可观察物没有影响时-链已切换。要影响链(而不只是影响可观察到的源主题),需要获取对订户的引用,然后调用该订户的unsubscribe()
方法。
要看到这一点,我分叉了您的CodeSandbox,并制作了此new one
正如您将在该CodeSandbox中看到的那样,我添加了几行以显示正在发生的事情:
tap()
-这将显示在使用switchMap运算符将链切换到其他Observable之前,从Subject()
直接进行的操作。sub
中,以后可以取消订阅该变量,以从下至上从上影响该链。s.complete()
会在10秒后反映在“主题”中,并注意它根本不会影响链接。sub.unsubscribe()
在15秒后确实会杀死链条。take(5)
方法中的newT()
的注释,以查看如果水龙头上方的源实际上完成了(tap-> down),则确实会调用水龙头的complete方法。 finalize()
捕获到发生退订(自下而上)的事实,请注意,在主题上调用switchMap()
时,s.next()
向上进行自动退订时都会发生源,以及在订阅上调用unsubscribe()
时,再次导致自下而上终止。绝对不会在原始观察者中调用您的complete()
,因为该链实际上从未完成。您可以根据需要使用take(10)
运算符来完成该链,以了解其工作原理。
希望这有助于消除混乱。 :)