我试图在RxJS中推断用户的生命周期。也就是说,我们都知道我们需要取消订阅一个可观察的对吧?但问题是:为什么?
我正在开发一个基于Angular的大型应用程序,所以我无法真正分享我的代码,但我会尝试为您提供思考实验的背景。让我们说我们有以下组件:
class Comp extends Component {
public o$;
constructor(private store$: Store) {}
ngOnInit() {
this.o$ = this.store$.pipe(select(...), map(...));
this.o$.subscribe(function() {
this.whateverFromComponent(); // Let's tie this to component via closure
});
}
}
所以我们可以写一些类似this.o$.pipe(takeUntil(this.onDestroy$))
但我使用原生角色路由器的东西,所以当我更改子页面时,Comp
类实例被删除,并且唯一引用{ {1}}被移除,因此删除了对回调的唯一引用,我们全部完成了吗?
但情况似乎并非如此:当从DOM中删除组件并调用o$
时,我预计onDestroy
的实例也会被删除,但它会#39 ; s显然没有删除,否则我们不需要取消订阅可观察资料。
所以我开始认为,Angular会创建一次组件的实例,并且当它未被使用时,不会删除对组件类实例的引用,而是保留以供进一步使用。但似乎并非如此,因为每次在页面上呈现组件时都会调用放入构造函数的comp
。
好的,所以在这一点上我知道组件实例在从DOM中删除时不会从内存中删除,因为无论如何都会调用订阅。每次将组件实例放入DOM时,都会创建组件实例。 Waaaat?
我已经运行DevTools并获取内存快照并过滤了我的组件类名称。事实上,似乎每次组件都在页面上呈现,就会创建一个新实例。因此,即使只需要一个组件,我也会得到n个参考组件。
我开始挖掘并从一些订阅中引用过时的组件实例,这似乎来自Angular Router。
你能否帮我弄清楚何时(如果有的话)是从内存中删除的Component类的实例?为什么订阅仍然存在?
答案 0 :(得分:1)
只要流处于活动状态,它显然需要对所有订阅的引用。否则它无法向订阅者发出值。但是,当流完成时,情况就不再如此。
在您的示例store$
中(很可能)永远不会完成,因此您需要取消订阅。否则,订阅以及流将保持活动状态(尽管名称store$
意味着此特定流可能与应用程序一样长。)
从内存中删除组件实例时,取决于垃圾收集器以及某些代码是否仍保留对该实例的引用。