使用Angular,我有一个组件中提供的服务。该服务有一个可观察对象,并且该组件订阅了这个可观察对象。我原以为我不需要取消订阅/可观察对象,因为该服务应该与组件一起销毁,因此也是可观察对象。然而,快速测试显示可观察对象是活动的。
在我的视线之外发生了什么?可观察对象是否在服务之外运行?或者当提供它的组件被销毁时,服务实际上并没有被销毁?
在你的场景中使用totoit。您需要创建/初始化一个主题,该主题将在组件销毁时完成。
private unsubscribe: Subject<void> = new Subject<void>();
this.testService.testObservable().pipe(takeUntil(this.unsubscribe))
.subscribe(data => console.log(data));
组件销毁完成订阅
使用主题和取值,您可以在ngOnDestory一次取消订阅多个可观察对象。
public ngOnDestroy(): void {
this.unsubscribe.next();
this.unsubscribe.complete();
}
如果你订阅了一个未完成的可观察对象,你就会有内存泄漏。即使服务是由组件提供的,你也在服务中创建了一个可观察对象并将其返回给组件。现在可观察对象被组件引用,不再与创建它的服务有任何关系。当组件被销毁时,它将被标记为垃圾回收机制,但仍然存在于内存中,直到垃圾收集器清理资源。你仍然需要取消订阅未完成的可观察对象。
有几个选择
带至的好处是,您可以使用它来管理多个订阅,而不必单独跟踪每个订阅。
1:异步管
data$ = this.testService.testObservable();
并认为
<ng-container *ngIf="data$ | async as data">
{{ data | json }}
</ng-container>
2:退订
this.subscription = this.testService.testObservable().subscribe(data => console.log(data));
ngOnDestroy() {
if (this.subscription) {
this.subscription.unsubscribe();
}
}
3:带至
finalise = new Subject<void>();
this.subscription = this.testService.testObservable().pipe(takeUntil(this.finalise)).subscribe(data => console.log(data));
ngOnDestroy() {
this.finalise.next();
this.finalise.complete();
}
当我们返回或使用间隔时,可观察对象将不断接收流,直到我们停止它。为最佳实践,您应该使用间隔可观察对象和RxJS运算符来自动销毁订阅。
// RxJS v6+
import { interval, timer } from 'rxjs';
import { takeUntil } from 'rxjs/operators';
//emit value every 1s
const source = interval(1000);
//after 5 seconds, emit value
const timer$ = timer(5000);
//when timer emits after 5s, complete source
const example = source.pipe(takeUntil(timer$));
//output: 0,1,2,3
const subscribe = example.subscribe(val => console.log(val));
[注意]如果您使用的是setInterval,则需要使用ngOnDestroy显式取消订阅