提问者:小点点

订阅的自定义完成方法是否会自行取消订阅?


我创建一个可观察的:

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),可观察对象在一个发出的值之后完成。所以完整的方法被调用,我们在那里做一些动作()。由于这个方法是自定义的,订阅是自己取消订阅,还是我必须在完整的方法中手动取消订阅?

编辑:如何在订阅的完整方法中取消订阅?


共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