为什么RxJS函数toPromise没有取消订阅

edd*_*P23 7 javascript promise observable rxjs

在我们的应用程序中,我们有很多地方可以使用:

someObservable.take(1).subscribe(onSuccessHandler, onFailureHandler);
Run Code Online (Sandbox Code Playgroud)

但是对于订阅,您需要担心在某个时候退订,这并不总是那么简单。

我当时想简化此过程并将其重写为:

someObservable.toPromise().then(onSuccessHandler).catch(onFailureHandler);
Run Code Online (Sandbox Code Playgroud)

但是,看一下toPromise()here)的实现,我似乎不明白为什么它不关心取消订阅。

代码中的注释说无法取消,但我们如何像这样将其保留以泄漏内存(以防实际情况)。

编辑

我想出了一个让我担心的例子:

Observable.timer(10, 10).toPromise().then((v) => console.log("I'm done"));
Run Code Online (Sandbox Code Playgroud)

如果我检索到的可观测值永远无法完成,那么不仅我的承诺永远不会完成,而且我也无法取消订阅此类可观测值(例如,使它们和我的承诺超时),因为我无权获取订阅对象。那确实会泄漏内存!

Mei*_*eir 5

我的猜测是,这是因为一个承诺只被解决了一次(不像一个序列是一个流)。请注意,订户始终保留最新值,失败时拒绝,并在完成时解析为最新值。

要自己尝试,请尝试:

    Observable.timer(300,300).take(4).toPromise().then((v) => console.log('tick: ', v)); // logs "3", the last element
    Observable.from(['a','b','c']).toPromise().then((v) => console.log('tick: ', v)); // logs "c", the last element
Run Code Online (Sandbox Code Playgroud)

至于退订,它是自动完成的,因此在完成之前,您不应该退订,在完成时,您应解决承诺并以静默方式(由于可观察对象的默认行为)取消订阅。


use*_*222 4

“无法取消”评论可能是指取消承诺,这与可观察的完成完全不同。关于该运算符的实现,如果仔细观察,您会发现它.subscribe是通过三个参数调用的:

  • onNext 处理程序保存流值
  • onError 处理程序拒绝承诺
  • 完成处理程序用所持有的值解决承诺

然后,Rxjs 流的工作方式是,当流完成时,会发生自动取消订阅链,就像订阅流时会发生自动订阅链一样。

欲了解更多信息,请查看此处