我创建一个可观察的:
public getData(): Observable<any> {
return this.getEndpoint()
.pipe(
switchMap((endpoint) =>
this.http.get<any>(endpoint)
),
take(1)
);
}
我订阅了可观察对象,HTTP调用被执行
this.getData().subscribe({
next: data => this.data = data,
complete: () => {
this.someActions();
},
});
由于可观察管道中的采取(1),可观察对象在一个发出的值之后完成。所以完整的方法被调用,我们在那里做一些动作()。由于这个方法是自定义的,订阅是自己取消订阅,还是我必须在完整的方法中手动取消订阅?
编辑:如何在订阅的完整方法中取消订阅?
您永远不需要取消订阅已完成的可观察对象。可观察对象通过对其观察者的完整()或错误()调用来完成。这是可观察对象契约的一部分。
考虑以下示例。
const sub = interval(250).pipe(
take(4),
map(x => x + 1)
).subscribe({
next: console.log,
complete: () => console.log("This observable completed naturally"),
err: _ => console.log("This observable completed with an error")
});
console.log("Sub is closed, no need to unsubscribe? " + sub.closed);
setTimeout(() => {
console.log("Sub is closed, no need to unsubscribe? " + sub.closed);
}, 1250);
控制台输出:
Sub is closed, no need to unsubscribe? false
1
2
3
4
This observable completed naturally
Sub is closed, no need to unsubscribe? true
这表明将完成的可观察对象不需要取消订阅,也不会造成内存泄漏。问题在于长期存在的可观察对象(例如没有采取
、采取
、采取时
、ect运算符的间隔)。
例如,在角度中,一些可观察对象需要在组件存在的时间内存在,但不再存在。它们与组件的生命周期相关联。问题是忘记取消订阅这样的可观察对象(那些本身没有完成的可观察对象)会导致内存泄漏。
of("Hello There").subscribe({
next: console.log,
complete: () => console.log("This observable completed naturally"),
err: _ => console.log("This observable completed with an error")
});
您不需要取消订阅此可观察对象。事实上,由于它是同步运行的,因此在您可以取消订阅之前,它将被关闭。
const sub = of(1).subscribe();
console.log(sub.closed); // output: true
const sub = interval(1000).subscribe(console.log);
setTimeout(() => {
console.log("Sub is closed: " + sub.closed);
sub.unsubscribe();
console.log("Sub is closed: " + sub.closed);
}, 60 x 60 x 1000);
在这里,我们启动一个可观察对象,然后等待一个小时看看它是否关闭。然后我们取消订阅并检查它是否关闭。这个间隔永远运行,直到它被显式取消订阅。
控制台输出:
0
1
2
... [skipping ahead]
3596
3597
3598
3599
Sub is closed: false
Sub is closed: true