【问题标题】:Is completing the Subject necessary when using the takeUntil pattern to unsubscribe from Observables?使用 takeUntil 模式取消订阅 Observables 时是否需要完成 Subject?
【发布时间】:2019-02-02 18:44:58
【问题描述】:

为了避免我的 Angular 应用程序中的内存泄漏,我使用以下众所周知的模式来取消订阅 Observables:

unsubscribe = new Subject();

ngOnInit() {
    this.myService.getStuff()
        .pipe(takeUntil(this.unsubscribe))
        .subscribe(result => {
            // processing the result
        });
}

ngOnDestroy() {
    this.unsubscribe.next();
}

这似乎工作正常,但在某些示例中,我注意到除了 next() 之外,complete() 上也调用了 complete()

ngOnDestroy() {
    this.unsubscribe.next();
    this.unsubscribe.complete(); // like this
}

这里有必要打电话给complete()吗?如果是这样,为什么?在这种情况下不调用complete()会有什么后果?

【问题讨论】:

标签: javascript angular rxjs


【解决方案1】:

让我们看看为什么你需要先退订。

非常简单:Observable 实例包含所有订阅的数组,这意味着您在 subscribe 中的每个回调都将保存在此数组中。这对 Component 来说是个坏消息,因为虽然它是从这些函数中引用的,但它不能被垃圾收集。我讲这些功能:

ngOnInit() {
    this.myService.getStuff()
        .subscribe(
            result => null, // this function will be stored in Observable
            error => null, // and this
            () => null, // and even this
        );
}

它适用于每个subscribe 调用。

现在你添加一个管道.pipe(takeUntil(this.unsubscribe))(或者你可以使用类似但更短的my small library)。事实上,你的 Observable 订阅了 Subject 的事件。而且,每当它发出一个值时,this.myService.getStuff() 返回的 Observable 将自行完成。这意味着上述所有三个函数都将从这个 Observable 的订阅数组中删除,并且不再从那里引用您的组件。

问题解决了。

以上所有你需要了解你所有的whys。

我们终于来回答你的问题了

ngOnDestroy() {
    this.unsubscribe.next();
    this.unsubscribe.complete();
}

complete 是不必要的,但也不会造成伤害。因为这个主题的唯一订阅者是来自 this.myService.getStuff() 的 Observable(或来自同一组件的其他 Observable)。这意味着这个 Subject 不会引用其他任何东西(唯一的侦听器被删除并且应该清除所有订阅的 complete 已经是空的),并且只要只有组件引用 Subject 作为它的属性,它们都将是由垃圾收集器收集。

【讨论】:

    【解决方案2】:

    这已经在前面讨论过,例如。这里Why a 'next' before 'complete' of Angular takeuntil ngUnsubscribe?

    您基本上不必致电complete(),因为next() 将处理链,takeUntil 将为您取消订阅this.unsubscribe。仅当您有一些与 this.unsubscribe 相关联的其他逻辑时,才可能需要调用 complete()

    无论如何,如果你打电话给complete(),你不会破坏任何东西。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-04-26
      • 2017-04-10
      • 1970-01-01
      • 2017-05-12
      • 2018-07-23
      • 1970-01-01
      • 2017-08-24
      • 2017-03-26
      相关资源
      最近更新 更多