首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >棱角服务被摧毁,但是为什么订阅仍然从可观察到的?

棱角服务被摧毁,但是为什么订阅仍然从可观察到的?
EN

Stack Overflow用户
提问于 2019-12-12 12:45:09
回答 5查看 4.5K关注 0票数 4

使用角,我有一个服务是在一个组件中提供的。该服务具有可观测性,并且该组件被订阅到此可观测项。我原以为我不需要取消订阅/可观察的订阅,因为应该用组件销毁服务,从而也可以观察到服务。然而,一个快速的测试显示,可以观察到的人是活着的。

在我的视线之外发生了什么?会在服务之外运行吗?或者当提供服务的组件被销毁时,服务实际上没有被销毁吗?

EN

回答 5

Stack Overflow用户

回答已采纳

发布于 2019-12-13 04:25:20

根据yurzui的评论,我得出以下结论:

尽管服务被破坏(就像在被破坏的组件中提供的那样),可观察和订阅仍然在服务和组件之外工作。我认为这在某些时候不会被收集到,所以我明确地清理了它。

我的问题不是如何从可观察到的订阅中取消订阅,但无论如何,我认为分享我的实际解决方案来管理我预期会被销毁的订阅是有用的。我在服务上创建了一个destroy()函数,父组件在ngOnDestroy循环中调用该函数。在这个函数中,我从服务中的所有无限可观测值中发出完整的。这就避免了重复自己和取消订阅所有子组件。

为我服务:

代码语言:javascript
复制
private subject = new BehaviorSubject<string>(null);

public testObservable(): Observable<string> {
    // ... 
    this.subject.next('result');
    return this.subject.asObservable();
}

destroy() {
    this.subject.complete();
}

在我的部分:

代码语言:javascript
复制
ngOnInit() {
   this.testService.testObservable().subscribe(data => console.log(data));
}

ngOnDestroy() {
    this.testService.destroy();
}

编辑

我已经包括了一个工作的堆栈闪电战,以防我的解决方案有一些不确定性:https://stackblitz.com/edit/destroyservice。我喜欢的是,我用3行代码从6个订阅中取消订阅,并且不需要在任何子组件中包含ngOnDestroy。

票数 -1
EN

Stack Overflow用户

发布于 2019-12-12 12:53:51

首先要注意的是,角服务是单例的,不会被破坏。

其次,您的可观测性是在您的组件中订阅的,而不是在您的服务中。最后要回答你的问题,

当组件被销毁时,订阅不会被销毁。您将不得不手动取消订阅。有几种方法可以做到这一点,最简单的是

-不要订阅,而是在模板中使用异步管道.

了解更多关于取消订阅组件上所有订阅的更好方法的在媒体上阅读这篇博文

票数 0
EN

Stack Overflow用户

发布于 2019-12-13 04:33:28

如果订阅未完成的可观察到的内容,则会出现内存泄漏。即使服务是由组件提供的,也可以在服务中创建一个可观察的服务,并将其返回给组件。现在,可观察性被组件引用,并且不再与创建它的服务有关。当组件被销毁时,它将被标记为垃圾收集,但在垃圾收集器清理资源之前,它仍然存在于内存中。您仍然需要取消订阅未完成的可观察到的内容。

有几种选择

  1. 使用异步管道,因为它将为您管理订阅并取消订阅。
  2. 保持对订阅的引用,并在ngOnDestroy上调用取消订阅
  3. 使用采取,直到一个主题,并使主题发出一个ngOnDestroy。

takeUntil的好处是您可以使用它来管理多个订阅,而不必单独跟踪每个订阅。

1:异步管道

代码语言:javascript
复制
data$ = this.testService.testObservable();

在视野中

代码语言:javascript
复制
<ng-container *ngIf="data$ | async as data">
  {{ data | json }}
</ng-container>

2:取消订阅

代码语言:javascript
复制
this.subscription = this.testService.testObservable().subscribe(data => console.log(data));

ngOnDestroy() {
  if (this.subscription) {
    this.subscription.unsubscribe();
  }
}

3: takeUntil

代码语言:javascript
复制
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();
}
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/59304913

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档