为什么RxJS函数toPromise不会取消订阅

时间:2016-10-06 15:05:40

标签: javascript promise rxjs observable

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

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

但是对于订阅,您需要担心在某些时候取消订阅,这并不总是直截了当。

我正在考虑简化这个并将其重写为:

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

但是看看toPromise()here)的实施情况,我似乎并不理解为什么它不关心取消订阅。

代码中的注释表示不能取消,但我们如何将它留下来泄漏内存(如果我们确实存在)。

修改

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

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

如果我检索到的可观察物是他们永远不会完成的,那么不仅我的承诺永远不会带有价值,而且我也无法取消订阅这些可观察物(例如超时和我的承诺),因为我有无权访问订阅对象。这确实泄漏了记忆!

2 个答案:

答案 0 :(得分:3)

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

要尝试自己,请尝试:

    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

至于取消订阅,它在完成时是自动的,所以在完成之前,你不应该在完成时取消订阅,解决承诺并默默地(由于可观察的默认行为)取消订阅。

答案 1 :(得分:2)

'不能取消'评论可能是指取消承诺,这与可观察完成完全不同。关于该运算符的实现,您将看到是否仔细观察,使用其三个参数调用.subscribe

  • onNext处理程序,用于保存流值
  • onError处理程序拒绝承诺
  • 使用保留值解析承诺的完成处理程序

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

如需更多信息,请查看here