Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/kubernetes/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
rxjs开关映射和分接问题_Rxjs_Switchmap - Fatal编程技术网

rxjs开关映射和分接问题

rxjs开关映射和分接问题,rxjs,switchmap,Rxjs,Switchmap,我在玩弄switchMap操作符,以清楚地了解“切换”内部可观察对象发生了什么 起初我以为switchMap只是“取消订阅”切换的内部可观察对象,但后来我意识到它实际上是“取消订阅并完成内部可观察对象” 为了确认我已经写了这个小片段: 如您所见,主题第二次发射时正确调用了finalize()操作符,但是: 为什么不调用tap运算符的完整处理程序 这让我对这个操作员的理解只感到80%的高兴 与此无关的一个问题: 我已经阅读并观看了许多关于switchMap的资料,包括: 这(伟大的)ngcon

我在玩弄switchMap操作符,以清楚地了解“切换”内部可观察对象发生了什么

起初我以为switchMap只是“取消订阅”切换的内部可观察对象,但后来我意识到它实际上是“取消订阅并完成内部可观察对象”

为了确认我已经写了这个小片段:

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

这让我对这个操作员的理解只感到80%的高兴

与此无关的一个问题:
我已经阅读并观看了许多关于switchMap的资料,包括:

  • 这(伟大的)ngconf来源:
  • rxjs官方文件:
它们都没有明确说明内部可观察性是未订阅的还是未订阅且关闭的(或者至少我不理解:)

我已经看过switchMap操作符的源代码,但是没有提到takeXXX操作符,没有它他怎么能完成内部操作符呢

tl;dr

  • 您确认切换时switchMap完成内部可观察吗
  • 为什么tap操作员不能按预期工作
  • 如果switchMap有效地完成了内部可观察性,那么他如何在内部不使用takeXXX操作符的情况下实现这一点

我认为您混淆了
unsubscribe()
complete()
之间的区别。对于像
对象这样的热门观察对象
,您可以通过几种方式“阻止”它。使用
complete()
从“top->down”开始,就像您在示例中所做的那样,或者使用
unsubscribe()
从“bottom->up”开始

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

为了看到这一点,我将您的代码沙盒分叉,并制作了这个

正如您将在代码沙盒中看到的,我又添加了几行代码来显示发生了什么:

  • 注意开关映射正上方的链中新的
    tap()
    -这将显示在使用开关映射操作符将链切换到不同的可观察对象之前,直接从
    Subject()
    进行的操作
  • 链的订阅现在被捕获在变量
    sub
    中,稍后可以取消订阅以从下到上影响链
  • 请注意,10秒后的
    s.complete()
    现在会反映在主题中,还要注意它如何完全不影响链
  • 现在请注意,新的
    sub.unsubscribe()
    在15秒后确实会杀死链
  • 取消对
    newT()
    方法中的
    take(5)
    的注释,以查看如果tap上的源实际完成(top->down),将调用tap的complete方法
finalize()
捕捉到取消订阅已发生的事实(从下到上),请注意,在主题源上调用
s.next()
时,以及在订阅上调用
unsubscribe()
时,都会发生取消订阅,这会再次导致底部->向上终止。在任何情况下,都不会在原始观察者中调用您的
complete()
,因为链从未实际完成。如果需要,您可以使用
take(10)
操作符来完成该链,以了解其工作原理


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

当一个被观察者没有更多的观察者时,它就完成了。不确定这个断言@WillAlexander,你是在一般情况下还是在问题的上下文中?我道歉,我说错了。我想说的是,当一个可观察对象没有更多订户时,它调用任何
finalize
回调并停止发送。从技术上讲,它并不完整。你是对的,看看这个片段:奇怪的是rxjs文档说finalize操作符是在完成或错误时调用的,而不是在“取消订阅”时调用的。对我来说,完成一个可观察到的和取消订阅一个观察者是两件不同的事情。Rxjs文档about finalize()说:“返回一个可观察对象,它镜像源可观察对象,但当源在完成或出错时终止时将调用指定的函数。”我的“错误”是,文档说finalize在完成时调用,但在这里,finalize不是在完成时调用,而是在“取消订阅”时调用。像这样的接缝引入了一种新的“状态”,比如:“未完成但未订阅”看看这段代码:codesandbox.io/s/switchmap-and-tap-issue-7sb1v?fontsize=14 IMHO这证实了你所说的以及@WillAlexander也在说的话。当订阅被取消订阅时,将调用finalize,这并不意味着观察者已完成。因此,我很想说doc对于finalize的调用不是100%准确。我认为
finalize
就像是观察值的
ngondestry
。如果你看一下时间,它甚至在订阅中任何
完成
回调后都会被调用。这就像是已经知道的事情:很好,我将在github上关注这个问题,看看这个问题会出现在哪里。:)