Javascript 当使用takeUntil模式取消订阅观察对象时,是否需要完成主题?

Javascript 当使用takeUntil模式取消订阅观察对象时,是否需要完成主题?,javascript,angular,rxjs,Javascript,Angular,Rxjs,为了避免Angular应用程序内存泄漏,我使用以下众所周知的模式取消订阅Observable: unsubscribe = new Subject(); ngOnInit() { this.myService.getStuff() .pipe(takeUntil(this.unsubscribe)) .subscribe(result => { // processing the result }); }

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

unsubscribe = new Subject();

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

ngOnDestroy() {
    this.unsubscribe.next();
}
这似乎很好,但在一些示例中,我注意到除了
next()
,还对
主题调用了
complete()


这里是否需要调用
complete()
?若然,原因为何?在这种情况下,不调用
complete()
会产生什么后果?

前面已经讨论过这一点,例如这里

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


无论如何,如果调用
complete()

我们来看看为什么需要先取消订阅

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

ngOnInit() {
    this.myService.getStuff()
        .subscribe(
            result => null, // this function will be stored in Observable
            error => null, // and this
            () => null, // and even this
        );
}
它适用于每个
订阅
呼叫

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

问题解决了

综上所述,您需要了解您拥有的所有
原因

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

ngOnDestroy() {
    this.unsubscribe.next();
    this.unsubscribe.complete();
}
其中,
complete
是不必要的,但也不有害。因为这个主题的唯一订阅者是来自
this.myService.getStuff()
(或来自同一组件的其他可观察对象)的可观察对象。这意味着这个主题将不引用任何其他内容(应该清除所有订阅的唯一侦听器被删除并且
complete
已为空),并且只要只有组件引用了主题作为其属性,它们都将由垃圾收集器收集

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