Angular - 终止Observables的首选方法是什么?

时间:2017-07-26 17:37:50

标签: angular rxjs rxjs5 angular2-observables unsubscribe

根据我对Angular和RxJ的理解,有两种方法可以终止Observable。您可以unsubscribe()从他们那里使用takeUntil()complete()。以下是每种方法的示例(伪代码)。

取消订阅()方法

private _id: number;
private _subscriptions: Subscription[] = [];

constructor(private _route: ActivatedRoute) {
    this._getId();
}

public ngOnDestroy(): void {
    this._subscriptions.forEach(
        subscription => subscription.unsubscribe()
    );
}

private _getId(): void {
    this._subscriptions.push(
        this._route.params.subscribe(params => this._id = +params['id'])
    );
}

takeUntil()和complete()方法

private _id: number;
private _ngUnsubscribe: Subject<void> = new Subject<void>();

constructor(private _route: ActivatedRoute) {
    this._getId();
}

public ngOnDestroy(): void {
    this._ngUnsubscribe.next();
    this._ngUnsubscribe.complete();
}

private _getId(): void {
    this._route.params.takeUntil(this._ngUnsubscribe).subscribe(
        params => this._id = +params['id']
    );
}

在Angular中,是否有一种终止Observables的首选方法?

2 个答案:

答案 0 :(得分:7)

两种方法都是正确的,即使它们不相同。

在我看来(和经验)使用unsubscribe()通常更有意义,对于没有RxJS丰富经验的其他开发人员来说更为明显。

RxJS 5(https://medium.com/@benlesh/rxjs-dont-unsubscribe-6753ed4fda87)的首席开发人员建议使用takeUntil(),有时比处理多个订阅对象更容易使用。例如,如果您使用partition()运算符将一个流拆分为两个,则更容易使用takeUntil(...).partition(...)

然而,有两件重要的事情:

  1. 这两个不一样。如果使用takeUntil(),则表示您正在完成Observable链,这意味着将调用所有完整句柄,然后调用拆除函数。另一方面,当您致电unsubscribe()时,只会调用拆除功能(包括finally()等运营商。)

    这就是我认为使用unsubscribe()更有意义的原因。使用takeUntil(),即使您只想取消订阅,也可能会调用complete处理程序(不提及这会触发使用complete信号的运算符,例如repeat()可能会再次重新订阅)。您要取消订阅的事实并不意味着源Observable已完成。你只是不再关心它的值,所以在这种情况下使用unsubscribe()可能更好。

    然而,在实践中,无论您是完成连锁还是取消订阅都无关紧要。

  2. 您可以将Subscription组成一个,并立即取消订阅所有这些:

    const subscription = new Subscription();
    
    const sub1 = Observable...subscribe(...);
    const sub2 = Observable...subscribe(...);
    const sub3 = Observable...subscribe(...);
    
    subscription.add(sub1).add(sub2).add(sub3);
    
    ...
    
    subscription.unsubscribe(); // unsubscribes all of them
    

答案 1 :(得分:0)

我这样做的方法是首先检查ngOnDestroy,如果Observable存在。如果是,则取消订阅。以下是我的应用中的代码段。

 accountSubscriptionObj : Subscription;

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

同时,您不需要取消订阅Async管道,@ HostListener, 有限可观察。 当组件被销毁时,异步管道会自动取消订阅以避免潜在的内存泄漏。当您有一个有限的序列时,通常您不需要取消订阅,例如在使用HTTP服务或计时器可观察时。有关更多参考read here