组件销毁后,可观察的订阅保持活动状态

时间:2018-09-20 20:20:12

标签: angular

我的一个组件订阅了路由器事件,如下所示:

    this.navigationSubscription = this.router.events.subscribe((e: any) => {
      // If it is a NavigationEnd event re-initalise the component
      if (e instanceof NavigationEnd) {
        let p = e as NavigationEnd;
          console.log(p.urlAfterRedirects);
        console.log("im being called from NavigationEnd");
        this.ngOnInit();
      }
    });
   }

当用户第二次通过按钮导航到组件时,我使用此代码重新加载组件。在调试问题时,我注意到当我导航到另一个组件时,即使该部分不是该组件,该代码段仍保持活动状态。有人可以解释为什么即使组件本身不再存在,此代码仍保持活动的原因和方式?当代码无法再到达this.ngOnInit()时,代码是否会引起错误?

我可以通过在onDestroy方法中取消订阅来解决此问题,但是我真的很想知道当组件不再存在时代码如何能够保持活动状态,以及为什么this.ngOnInit()不抛出错误,因为该组件未激活。

3 个答案:

答案 0 :(得分:1)

通常来说,销毁组件后,所有订阅仍保持活动状态。

这是Angular IMO的最大痛苦之一。

但是,此规则有一些例外:

  • this.activatedRoute.params.subscribe-自动退订
  • this.activatedRoute.data.subscribe-自动退订
  • 任何http订阅-这些订阅将发出一次,然后完成,因此无需取消订阅
  • 异步管道自动取消订阅

对于其他所有内容,您都需要手动取消订阅。有多种方法可以执行此操作,但这是RxJs建议的方法:

window.onload = function() {
   console.log("page loaded");
   //your code here
}

答案 1 :(得分:1)

一个现实世界的例子,以及我如何理解订阅:如果我在街道地址订阅了报纸,而我的房屋被摧毁(插入坏场景),我仍然必须取消订阅,否则报纸会堆积如山在曾经是我家的被烧毁的堆上。

答案 2 :(得分:0)

  

有人可以解释为什么该代码仍然有效,以及为什么   组件本身不再存在?

尽管该组件“不再存在”,但这仅意味着指向其中存储的Subscription实例的指针已消失,但订阅仍处于“活动”状态,并且很可能被{{ 1}}流,解释了为什么GC无法简单地从内存中删除实例。

  

当代码无法再到达时,它不会引起错误   this.ngOnInit()吗?

很可能与第一点有关,因为GC无法释放组件实例。