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

时间:2017-09-26 16:01:07

标签: angular memory-management rxjs observable subscription

我已经阅读了大量有关Angular中Observable取消订阅的帖子,所有这些帖子都提到了仅需要在组件/指令中这样做。

所以我的问题是:

我们是否需要在非组件/指令类中取消订阅Observable,例如在服务中或基本上任何其他包含Observable s订阅的类?

2 个答案:

答案 0 :(得分:1)

您取消订阅组件,因为当您从DOM中删除它们时(例如,使用*ngIf或其他)RxJS链将保留对您在此处创建的观察者的引用。从而引入内存泄漏。

一般而言,您不必取消订阅服务,因为它们在您的应用程序的整个生命周期中都存在。

但是,在Angular中,您可以创建一个组件,例如仅为其后代提供不同的服务实例(这意味着您的应用程序中可能有多个相同服务类的实例)。在这种情况下,您应该手动取消订阅(可能在销毁定义它们的组件时)。

答案 1 :(得分: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.
      };
    });

  }
}

还有其他更好的方法来编写这段代码,这只是一个例子。所以在这种情况下,我们有一个非Component / Directive订阅会话。每次会话更改时,我们都会查看用户是否已登录并通知我们的侦听器是否存在。如果每个人都取消订阅 us ,我们仍然会收听this.session,除非我们(服务)明确取消订阅。