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

8

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

someObservable.take(1).subscribe(onSuccessHandler, onFailureHandler);

但是对于订阅服务,您需要考虑在某个时候取消订阅,而这并不总是那么简单。

我想将其简化并重写为:

someObservable.toPromise().then(onSuccessHandler).catch(onFailureHandler);

但是,看到toPromise()的实现方式(这里),我不明白为什么它不关心取消订阅。
代码中的注释说无法进行取消操作,但如果我们真的像这样泄漏内存,该怎么办呢? 编辑 我想出了一个让我担忧的例子:
Observable.timer(10, 10).toPromise().then((v) => console.log("I'm done"));

如果我获取的可观察对象永远不会完成,那么不仅我的承诺永远不会以值完成,而且我也无法取消订阅这些可观察对象(例如超时它们和我的承诺),因为我没有订阅对象的访问权限。这样会导致内存泄漏!
2个回答

6

我的猜测是,这是因为Promise只会被解决一次(不像序列是一个流)。请注意,订阅者始终保持最新的值,在失败时拒绝并在完成时解决到最新的值。

要自己尝试,请尝试:

    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

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


4
“无法取消”注释可能是指取消承诺,这与可观察完成完全不同。关于该运算符的实现,如果你仔细观察,就会发现 .subscribe 是带有三个参数调用的:
  • onNext 处理程序,保存了流式值
  • onError 处理程序,拒绝承诺
  • 完成处理程序,使用保存的值解决承诺
然后 Rxjs 流的工作方式是,当流完成时,自动进行取消订阅链,就像当流订阅时,自动进行订阅链一样。
想要了解更多信息,请查看这里

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接