问题描述
据我对Angular和RxJ的理解,有两种终止Observable的方法.您可以从中unsubscribe()
或使用takeUntil()
和complete()
.下面是每种方法的示例(使用伪代码).
From my understanding of Angular and RxJs there are two ways to terminate Observables. You can unsubscribe()
from them or use takeUntil()
and complete()
. Below are examples of each approach (in pseudocode).
unsubscribe()方法
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中,有没有一种终止Observable的首选方法?
In Angular, is there a preferred way to terminate Observables?
推荐答案
这两种方法即使不等效也都是正确的.
Both approaches are correct even though they aren't equivalent.
根据我的观点(和经验),使用unsubscribe()
通常更有意义,并且对于其他没有使用RxJS的丰富经验的开发人员来说更明显.
In my opinion (and experience) using unsubscribe()
make usually more sense and is more obvious to other developers that don't have extensive experience with RxJS.
RxJS 5的首席开发人员建议使用takeUntil()
( https://medium.com/@benlesh/rxjs-dont-unsubscribe-6753ed4fda87 ),有时比处理多个订阅对象更容易使用.例如,如果使用partition()
运算符将一个流分成两部分,则仅使用takeUntil(...).partition(...)
会更容易.
Using takeUntil()
is recommended by the lead developer of RxJS 5 (https://medium.com/@benlesh/rxjs-dont-unsubscribe-6753ed4fda87) and is sometimes easier to use than handling multiple subscription objects. For example if you use the partition()
operator to split one stream into two it's easier to use just takeUntil(...).partition(...)
.
但是有两个重要的事情:
However there are two important things:
-
这两个不一样.如果使用
takeUntil()
,则说明正在完成Observable链,这意味着将调用所有完整的句柄,然后调用拆解函数.另一方面,当您调用unsubscribe()
时,仅调用拆卸功能(包括诸如finally()
之类的运算符).
These two aren't the same. If you use
takeUntil()
you're completing the Observable chain which means that all complete handles are called followed by tear down functions. On the other hand when you callunsubscribe()
only tear down functions are called (including operators such asfinally()
).
这就是为什么我认为使用unsubscribe()
更有意义.使用takeUntil()
,即使您只是想退订,您也可能会调用一个complete
处理程序(更不用说这会触发使用complete
信号的运算符,例如repeat()
可能会再次订阅).您要退订的事实并不意味着源Observable已完成.您只是不再关心它的值,因此在这种情况下使用unsubscribe()
可能更好.
This is why I think it makes more sense to use unsubscribe()
. With takeUntil()
you might have a complete
handler that is invoked even though you just wanted to unsubscribe (not mentioning that this triggers operators that work with the complete
signal such as repeat()
that might resubscribe again). The fact you want to unsubscribe doesn't mean that the source Observable completed. You just don't care any more about its values so it's probably better to use unsubscribe()
in this case.
但是,实际上,完成连锁还是取消订阅通常并不重要.
However, in practise it usually doesn't matter whether you complete the chain or just unsubscribe.
您可以将Subscription
组合成一个,然后一次取消所有订阅:
You can compose Subscription
s into a single one and unsubscribe all of them at once:
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
这篇关于角度-终止Observable的首选方法是什么?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!