在非组件/指令类中取消订阅 Observable
Posted
技术标签:
【中文标题】在非组件/指令类中取消订阅 Observable【英文标题】:Unsubscribing from Observable in a non-Component/Directive class 【发布时间】:2018-03-07 22:49:22 【问题描述】:我已经阅读了大量关于在 Angular 中取消订阅 Observable
s 的帖子,所有帖子都提到仅在组件/指令中需要这样做。
所以我的问题是:
我们是否需要取消订阅非组件/指令类中的Observable
s,例如在包含订阅Observable
s 的服务或基本上任何其他类中?
【问题讨论】:
【参考方案1】:我认为说明为什么退订很重要很重要。从来没有必要从流中取消订阅,但可以提高性能,并且在某些情况下,取消订阅作为功能的一部分很重要。
同样重要的是,取消订阅是消费者的责任。流“强制”消费者取消订阅的唯一方法是完成或出错。
在 Angular 服务中,如果您最终订阅了流,那么取消订阅是一种很好的做法,除非您有充分的理由继续收听。这是一个(人为的)示例:
import Injectable from '@angular/core';
import Observable from 'rxjs';
@Injectable()
export class MyService
constructor( private session: Session )
isLoggedIn(): Observable<boolean>
return Observable.create( observer =>
const innerSubscription = this.session.subscribe( session =>
if ( session.user.isLoggedIn )
observer.next( true );
observer.next( false );
);
return function unsubscribe()
innerSubscription.unsubscribe(); // this "cleans up" our subscription.
;
);
还有其他更好的方法来编写此代码,这只是一个示例。所以在这种情况下,我们有一个订阅会话的非组件/指令。每次会话更改时,我们都会查看用户是否登录并通知我们的侦听器是否登录。如果每个人都取消订阅 us,除非我们(服务)明确取消订阅,否则我们仍会收听 this.session
。
【讨论】:
【参考方案2】:您取消订阅组件是因为当您从 DOM 中删除它们时(例如使用 *ngIf
或其他),RxJS 链将保存对您在其中创建的观察者的引用。从而引入内存泄漏。
一般而言,您不必取消订阅服务,因为它们存在于您的应用程序的整个生命周期中。
但是,在 Angular 中,您可以创建一个组件,例如,仅向其后代提供不同的服务实例(这意味着您的应用程序中可能有多个相同服务类的实例)。在这种情况下,您应该手动取消订阅(可能在销毁定义它们的组件时)。
【讨论】:
因此,简而言之,我们可以设置一条规则:在 任何 种情况下,只要订阅的寿命应该短于 infinite @987654322,我们就必须取消订阅@。组件/指令中的订阅只是最常见的情况。是真的吗? @AlexanderAbakumov 是的,这基本上是我遵循的规则。 通常最好在服务的 ngOnDestroy 中手动取消订阅。如果服务由一个组件提供,然后被销毁(没有其他组件引用该服务,则该服务将被销毁,然后将调用其 on destroy 函数。 另外,对于在应用程序的生命周期内从未销毁的组件/服务,请注意单元测试的情况,这些组件可能会被销毁。在这种情况下,您要么仍然需要在组件/服务中取消订阅,要么需要在测试运行器的测试后挂钩中清理这些订阅。以上是关于在非组件/指令类中取消订阅 Observable的主要内容,如果未能解决你的问题,请参考以下文章