[英]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.