我应该取消订阅根 Angular 组件中的 observables 吗?

Posted

技术标签:

【中文标题】我应该取消订阅根 Angular 组件中的 observables 吗?【英文标题】:Should I unsubscribe from observables in root Angular component? 【发布时间】:2020-02-05 02:23:57 【问题描述】:

我的根(引导)Angular (6.x) 组件中有一个 Observable,AppComponent。 通常,我会在使用生命周期钩子 ngOnDestroy 调用 destroy() 时取消订阅任何打开的订阅。 由于 AppComponent 是应用程序的根,因此永远不会被销毁(除非整个应用程序被销毁),我是否还需要实现 ngOnDestroy 并且我是否需要为取消订阅而烦恼?

我无法找到这个看似常见的确切场景的答案。

例子:

export class AppComponent implements OnInit, OnDestroy 
  private tokenSubscription: Subscription;
  constructor(private dataSvc: DataService)  
  ngOnInit() 
    this.tokenSubscription = this.dataSvc.myObservable.subscribe((val) => 
      // do stuff
    );
  
  ngOnDestroy() 
    this.tokenSubscription.unsubscribe(); // Do I need this in root component?
  

谢谢!

【问题讨论】:

【参考方案1】:

AppComponent.ngOnInit() 中的一次性订阅没问题

Angular AppComponent 中的 RXJS 订阅不需要取消订阅,只要不重复创建新订阅即可。例如,如果订阅是在ngOnInitAppComponent 中创建的,只要它们是一次性操作即可。

在 Root 中提供的 Angular 服务最好是 Singleton Services

对于在根组件中创建的 Angular 服务,最好使用单例服务来确保应用中只存在一个实例。

最佳实践

虽然在根组件中有未取消订阅的订阅通常是可以的,但建议遵循管理订阅的最佳实践。

take(1) - 对于仅在应用程序启动期间发生一次的订阅,请使用 RXJS take(1) 运算符,它具有自动取消订阅的好处。 async Pipe - 在后台处理 RXJS 订阅并自动取消订阅。

使用take(1) 的示例

constructor(private dataSvc: DataService)  

ngOnInit() 
  this.dataSvc.myObservable.pipe(take(1)).subscribe((val) => 
    // do stuff
  );

The Best Way To Unsubscribe RxJS Observables In The Angular Applications!

【讨论】:

感谢您的信息!我确实以单例的形式提供根服务。包含的代码只是一个示例,用于演示可能需要也可能不需要 ngOnDestroy。

以上是关于我应该取消订阅根 Angular 组件中的 observables 吗?的主要内容,如果未能解决你的问题,请参考以下文章

您是不是需要取消订阅 Angular 中的路由器参数?

Angular RxJS Observable:takeUntil 与使用订阅取消订阅 [关闭]

在非组件/指令类中取消订阅 Observable

您应该在 Angular2 父/子组件层次结构中的哪个点订阅 observable?

取消订阅 Rxjs Observables

取消订阅 Angular 中的 observable