销毁组件的属性可以通过订阅访问 - 如何?

Destroyed component's properties are accessible via subscription - how?

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

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

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

确保在 ngOnDestroy 中进行清理,这样就不会出现此问题。

您必须像这样取消订阅:

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

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

如果您不这样做,您将遇到您所面临的问题,并且订阅将继续发出。对于 Angular.

的菜鸟来说,这是一个很大的问题

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

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