繁体   English   中英

在使用takeUntil模式取消订阅Observable时,是否需要完成主题?

[英]Is completing the Subject necessary when using the takeUntil pattern to unsubscribe from Observables?

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

unsubscribe = new Subject();

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

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

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

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

这里需要调用complete()吗? 如果是这样,为什么? 在这种情况下不调用complete()有什么后果?

让我们看看为什么你需要先取消订阅。

非常简化: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)) (或者你可以使用我的类似但更短的小型库 )。 实际上,您的Observable订阅了Subject的事件。 并且,每当它发出一个值时, this.myService.getStuff()返回的Observable将自行完成。 这意味着将从此Observable的订阅数组中删除上述所有三个函数,并且不再从那里引用您的组件。

问题解决了。

以上所有你需要了解你拥有的所有why

在这里,我们终于提出了你的问题

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

complete是不必要的,但也不是伤害。 因为此主题的唯一订阅者是来自this.myService.getStuff() Observable(或来自同一组件的其他Observable)。 这意味着,这一主题将是指没有别的(唯一的听众被删除, complete是应该清除所有的订阅已经为空),只要唯一组件具有参考主题作为其财产,它们都将被收集垃圾收集器。

这已在前面讨论过,例如。 为什么在Angular的'完成'之前'下一步'取消订阅?

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

无论如何,如果你调用complete() ,你不会破坏任何东西。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM