使用角,我有一个服务是在一个组件中提供的。该服务具有可观测性,并且该组件被订阅到此可观测项。我原以为我不需要取消订阅/可观察的订阅,因为应该用组件销毁服务,从而也可以观察到服务。然而,一个快速的测试显示,可以观察到的人是活着的。
在我的视线之外发生了什么?会在服务之外运行吗?或者当提供服务的组件被销毁时,服务实际上没有被销毁吗?
发布于 2019-12-13 04:25:20
根据yurzui的评论,我得出以下结论:
尽管服务被破坏(就像在被破坏的组件中提供的那样),可观察和订阅仍然在服务和组件之外工作。我认为这在某些时候不会被收集到,所以我明确地清理了它。
我的问题不是如何从可观察到的订阅中取消订阅,但无论如何,我认为分享我的实际解决方案来管理我预期会被销毁的订阅是有用的。我在服务上创建了一个destroy()函数,父组件在ngOnDestroy循环中调用该函数。在这个函数中,我从服务中的所有无限可观测值中发出完整的。这就避免了重复自己和取消订阅所有子组件。
为我服务:
private subject = new BehaviorSubject<string>(null);
public testObservable(): Observable<string> {
// ...
this.subject.next('result');
return this.subject.asObservable();
}
destroy() {
this.subject.complete();
}在我的部分:
ngOnInit() {
this.testService.testObservable().subscribe(data => console.log(data));
}
ngOnDestroy() {
this.testService.destroy();
}编辑
我已经包括了一个工作的堆栈闪电战,以防我的解决方案有一些不确定性:https://stackblitz.com/edit/destroyservice。我喜欢的是,我用3行代码从6个订阅中取消订阅,并且不需要在任何子组件中包含ngOnDestroy。
发布于 2019-12-12 12:53:51
首先要注意的是,角服务是单例的,不会被破坏。
其次,您的可观测性是在您的组件中订阅的,而不是在您的服务中。最后要回答你的问题,
当组件被销毁时,订阅不会被销毁。您将不得不手动取消订阅。有几种方法可以做到这一点,最简单的是
-不要订阅,而是在模板中使用异步管道.
了解更多关于取消订阅组件上所有订阅的更好方法的在媒体上阅读这篇博文
发布于 2019-12-13 04:33:28
如果订阅未完成的可观察到的内容,则会出现内存泄漏。即使服务是由组件提供的,也可以在服务中创建一个可观察的服务,并将其返回给组件。现在,可观察性被组件引用,并且不再与创建它的服务有关。当组件被销毁时,它将被标记为垃圾收集,但在垃圾收集器清理资源之前,它仍然存在于内存中。您仍然需要取消订阅未完成的可观察到的内容。
有几种选择
takeUntil的好处是您可以使用它来管理多个订阅,而不必单独跟踪每个订阅。
1:异步管道
data$ = this.testService.testObservable();在视野中
<ng-container *ngIf="data$ | async as data">
{{ data | json }}
</ng-container>2:取消订阅
this.subscription = this.testService.testObservable().subscribe(data => console.log(data));
ngOnDestroy() {
if (this.subscription) {
this.subscription.unsubscribe();
}
}3: takeUntil
finalise = new Subject<void>();
this.subscription = this.testService.testObservable().pipe(takeUntil(this.finalise)).subscribe(data => console.log(data));
ngOnDestroy() {
this.finalise.next();
this.finalise.complete();
}https://stackoverflow.com/questions/59304913
复制相似问题