我有一个关于使用 Angular 和 RxJs 的 takeUntil 运算符取消订阅的常见模式之一的问题。在这篇文章中,它在第三个位置。例如,我们在组件类中有这样的代码:
private destroy$: Subject<boolean> = new Subject();
ngOnInit() {
this.control.
.pipe(takeUntil(this.destroy$)
.subscribe(doSmthngFunc);
}
ngOnDestroy() {
this.destroy$.next(true);
// Which next line of code is correct?
// this.destroy$.complete() // this one?
// this.destroy$.unsubscribe() // or this one?
}
第一行 this.destroy$.next(true) 是完全清楚的。但第二个不是。如果我们研究这些方法的实现,我们会发现它们的行为有些相似。 完成(): 取消订阅():
据我了解,在语义上 complete() 更可取,因为我们在组件生命周期中第一次和最后一次调用 next(),然后我们完成了这个 Subject,将其视为 Observable 并可以调用 complete()。这些方法属于观察者,取消订阅属于可观察对象,我们没有要取消订阅的订阅。但在底层,这些方法有类似的代码:
this.isStopped = true; // both
this.observers.length = 0; // complete
this.observers = null; // unsubscribe
this.closed = true; // only unsubscribe
理论上,complete() 具有延迟效果,因为它可能会在每个订阅的观察者上调用 complete(),但我们在 destroy$ 上没有观察者。那么问题来了——哪种方式更可取,更不容易出错,为什么?