Javascript 当使用takeUntil模式取消订阅观察对象时,是否需要完成主题?
为了避免Angular应用程序内存泄漏,我使用以下众所周知的模式取消订阅Observable: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 }); }
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();
}