【问题标题】:Is there a way to unsubscribe to a BehaviorSubject without assignment?有没有办法在没有分配的情况下取消订阅 BehaviorSubject?
【发布时间】:2018-07-07 08:34:39
【问题描述】:

有时我想订阅一个可观察对象,只是为了让一个发射触发其他事件。例如,订阅路由中的查询参数,以便从发出触发另一个事件 - 其中发出的值实际上并不重要。或者例如,如果我有一个 BehaviorSubject 并且需要根据对该主题的更改重新加载某些组件。在这些情况下,observable 并不意味着被模板使用,并且它们发出的值在很大程度上被忽略了。

理想情况下,我会写如下内容:

ngOnInit() {
    this.service.behaviorSubject.subscribe(
        () => callLocalMethod()
    )
}

问题是,一旦组件被销毁,angular 不会取消订阅该订阅,这意味着每次初始化和销毁​​组件时,除了旧订阅之外,还会创建一个新订阅,并调用从 observable 发出的订阅每个冗余订阅。在 OnDestroy 生命周期钩子中取消订阅是不可能的(据我所知),因为订阅没有分配给一个属性——但是对于这个用例来说,将它分配给一个属性似乎是不必要的。

所以我最终要做的是为每个订阅创建一个属性,即使该属性永远不会被使用,将其分配给订阅,然后在组件被销毁时调用unsubscribe()

这似乎真的多余 - 有更好的方法吗?使用异步管道处理订阅不是一种选择,而使用 EventEmitter 也不是一种选择,因为通常希望它表现得像一个热的 observable。

【问题讨论】:

  • 不确定,试试类似:subscribe(() => {}).unsubscribe()。看看有没有效果?
  • 在 subscribe() 之后立即调用 unsubscribe() 不起作用。
  • this.service.observable.unsubscribe() 在 ngOnDestroy 中不起作用吗?你试过吗?
  • 好的,知道了。我想我不知道其他方法,除了分配。
  • @varunsingh 不行,不能退订observable的注入实例。

标签: angular rxjs rxjs5 reactive behaviorsubject


【解决方案1】:

您可以使用其他主题:

private destroy$ = new Subject();

constructor() {
  obs$
    // Ensures that we complete when the component is
    // destroyed. Completing will automatically unsubscribe. 
    .takeUntil(this.destroy$)
    .subscribe();
} 

ngOnDestroy() {
  this.destroy$.next();
  this.destroy$.complete();
}

这样做的好处是它可以很好地扩展,因为无论您管理的订阅数量如何,样板都只需要一次。

还要注意,ActivatedRouter实际上是在组件销毁的时候完成params/paramMap,所以参数变化不需要手动取消订阅。

【讨论】:

  • 我刚刚意识到,在提出问题并进行一些测试之后,这实际上只是主题的问题,所以你说得对,ActivatedRouter params sub 不会有问题。还要感谢 takeUntil 运营商的建议,这对于只有少数订阅的组件有点多余,但仍然可能是可用的最佳解决方案。
  • 我个人在任何地方都使用 takeUntil,因为我发现它更适合响应式模式。管道已经告诉您它将被取消订阅。
【解决方案2】:

使用 takeWhile 你可以简单地使用一个布尔变量

private alive: boolean = true; //we use a variable
//All ours subscriptions are like
this.service.method()
      .takeWhile(() => this.alive)
      .subscribe(result => {...})

//in ngOnDestroy
public ngOnDestroy() {
    this.alive = false;
  }

【讨论】:

  • 是的,我也认为创建一个额外的主题是多余的。谢谢埃利塞奥!
猜你喜欢
  • 1970-01-01
  • 2016-04-04
  • 1970-01-01
  • 2016-01-21
  • 2020-11-14
  • 2019-11-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多