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

eba*_*nin 8 unsubscribe rxjs rxjs5 angular2-observables angular

根据我对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'])
    );
}
Run Code Online (Sandbox Code Playgroud)

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']
    );
}
Run Code Online (Sandbox Code Playgroud)

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

mar*_*tin 7

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

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

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

但是有两件重要的事情:

  1. 这两个不一样.如果您使用takeUntil()完成Observable链,这意味着调用所有完整的句柄,然后调用拆卸功能.另一方面,当你调用unsubscribe()只有拆除函数被调用(包括运算符finally()).

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

    但是,在实践中,无论您是完成链条还是仅取消订阅,通常都无关紧要.

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

    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
    
    Run Code Online (Sandbox Code Playgroud)