0

我有这个示例 stackblitz,我在其中为组件设置了一个“id”,您可以通过复选框创建和销毁该组件。每次创建组件的新实例时,都会给它一个递增的 id。在每个组件中,都有一个interval哪个控制台记录组件的 ID。我没有在销毁时取消订阅它。正如预期的那样,组件被销毁后我继续看到日志。让我感到困惑的是,不知何故,interval它仍然知道它来自哪个组件,并且在引用它的 id 时不会引发错误。如果组件被销毁,它的属性如何仍然可以访问?该组件是否仍然以某种方式存在,从而造成内存泄漏?

4

2 回答 2

1

在阅读了更多关于 JS 垃圾收集的内容后,我意识到这是一个棘手的问题。在 JavaScript 中,无法像在其他一些语言中那样显式地“处置”对象。当 Angular 销毁一个组件时,它会删除它的所有引用,然后垃圾收集器将它从内存中删除。通过在订阅回调中引用它,我实际上是在告诉 GC 不要清理组件。

所以是的,Angular 在销毁时确实“清理”了一个组件,因为它准备组件以供 GC 删除。但是,如果该组件仍然在其他地方引用,GC 当然不会删除它。

于 2021-08-04T17:05:06.757 回答
1

确保您在 ngOnDestroy 中进行清理,您不会遇到此问题。

您必须像这样取消订阅:

sub = this.myService.getObservable().subscribe();

ngOnDestroy(): void {
  this.sub.unsubscribe();
}

如果您不这样做,您将遇到您面临的问题,并且订阅将继续发送。对于 Angular 的新手来说,这是一个很大的问题。

当一个组件有多个订阅并且使用 RxJS 运算符 takeUntil 有更好的模式和更少的代码脚手架时,这种模式会变得很烦人。

您还必须确保在销毁组件时在任何活动间隔或超时上调用 clearInterval 和 clearTimeout。

于 2021-08-05T01:42:23.297 回答