【问题标题】:Do Subscription instances without reference handles need to be unsubscribed?没有引用句柄的订阅实例是否需要取消订阅?
【发布时间】:2019-05-19 12:17:22
【问题描述】:

只是好奇是否需要取消订阅未被引用的Subscription 实例?例如this demo 调用:

onSubmit(creds: Creds) {
   this.authService.login(creds).subscribe();
}

因此,每次有人登录时都会创建并返回 Subscription 实例,但它没有句柄。

IIUC 这些只会被垃圾收集,但为了安全起见,我会仔细检查。

【问题讨论】:

  • 是的,这些需要在 OnDestroy() 方法中捕获和取消订阅
  • 如果我们不这样做会造成内存泄漏?
  • 是的,当然可以
  • 您不必取消订阅将完成的可观察对象,但您需要注意它在引用它的对象的生命周期内完成。对于组件,这是在调用 OnDestroy 之前。
  • Observables 不必完成。完成一个 observable 并不能防止内存泄漏,但是永远订阅一个永远不会完成的 observable 会造成内存泄漏。因此,需要担心的是订阅者而不是发射器(即可注入服务)。

标签: javascript node.js angular typescript rxjs


【解决方案1】:

如果 Observable 完成,则无需取消订阅。使用 http 服务创建的 Observable 将在调用后完成。

也就是说,最好还是取消订阅或有一个 takeUntil 子句。

finalise = new Subject<void>();

onSubmit(creds: Creds) {
  this.authService.login(creds).pipe(takeUntil(finalise)).subscribe();
}

ngOnDestroy() {
  this.finalise.next();
  this.finalise.complete();
}

这样您就可以使用同一个主题来完成所有的 Observable,而不是管理许多订阅。

【讨论】:

  • 这样做的好处是,如果组件在完成之前被销毁,它将“取消”一个 HTTP 请求。
  • @cgTag 好提示!
  • 您不必将主题定义为布尔值。你可以让它voidfinalize = new Subject&lt;void&gt;();,然后是 this.finalize.next()。这基本上会发出一个 undefined 值。
  • 还要确保 takeUntil 子句是管道中的最后一个函数,将任何其他函数(如 map 和 filter)放在前面。
  • 无论什么类型的 Observable,它都适用于任何订阅。
猜你喜欢
  • 2017-05-12
  • 2019-01-31
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-07-23
  • 2021-04-01
  • 1970-01-01
相关资源
最近更新 更多