为啥组件销毁后订阅仍然存在?

Posted

技术标签:

【中文标题】为啥组件销毁后订阅仍然存在?【英文标题】:Why subscription survives after component destroyed?为什么组件销毁后订阅仍然存在? 【发布时间】:2018-09-18 16:07:01 【问题描述】:

我的 Angular 应用程序有很多组件,一个是 MyComponent,它的组件类如下所示:

import  Component, OnInit  from '@angular/core';
import  Observable  from 'rxjs/Observable';
import 'rxjs/add/observable/interval';

@Component(
  selector: 'app-my',
  templateUrl: './my.component.html',
  styleUrls: ['./my.component.scss']
)
export class MyComponent implements OnInit 
  a = 'I still alive';
  constructor() 

  ngOnInit() 
    Observable.interval(1000).subscribe(x => console.log(this.a));
  

如果我访问 MyComponent,订阅会按预期开始。说,我现在离开 MyComponent 并且 MyComponent 现在应该被销毁。但我仍然可以看到订阅仍然存在(控制台日志不断出现)。在宿主组件(MyComponent)被销毁后允许订阅继续存在的实际好处是什么?

(如果我想取消订阅,可以在MyComponent的ngOnDestroy()方法中完成,但是如何取消订阅不是这里讨论的重点)

【问题讨论】:

因为订阅是独立于组件的,这就是unsubscribe存在的原因 订阅独立于组件,这就是取消订阅存在的原因,是的,这很明显。但是,这是如何工作的?订阅保存在哪里?为什么在组件销毁时保留它? 它保存在内存中,因此得名内存泄漏。 ***.com/questions/34442693/… 订阅就像一个独立的线程。它不依赖于组件。组件只有一个参考。您只能使用 ngOnDestroy() this.subscription.unsubscribe(); 销毁 【参考方案1】:

在我对该主题进行了一些研究之后,我发现我不需要取消订阅 Angular 管理的一些订阅,例如在 ActivatedRoute 上进行的订阅。这就是official guide 所说的:

当订阅组件中的 observable 时,您几乎总是 安排在组件被销毁时取消订阅。

有一些特殊的 observables 是不必要的。 ActivatedRoute 可观察对象属于例外。

ActivatedRoute 及其 observables 与 Router 隔离 本身。当路由组件不再存在时,路由器会销毁它 需要,注入的 ActivatedRoute 也随之消亡。

请随时取消订阅。它是无害的,绝不是坏事 练习。

如果我必须退订,建议使用有效的generalized approach。

【讨论】:

【参考方案2】:

observable 是 RxJS 的一个概念,独立于 Angular 生命周期。

到目前为止,您订阅的 stream of data 已独立于 Angular 生命周期进行订阅和监控。因此,即使component 被销毁,内存也会保留引用,因此我们会出现内存泄漏。

因此,我们需要在destroy 阶段通过unsubscribingobservable 明确告诉RxJS 删除该引用。

【讨论】:

以上是关于为啥组件销毁后订阅仍然存在?的主要内容,如果未能解决你的问题,请参考以下文章

组件销毁并重新访问后,订阅在 ngOnInit 函数中运行

如何在组件销毁时销毁反应式 FormControl?

(Angular)从子级销毁父级订阅

js 事件发布订阅销毁

Angular 9:销毁子组件后向父组件发送数据

运行测试后销毁App组件