【问题标题】:Should I unsubscribe after complete invoked in rxjs?在 rxjs 中调用完成后我应该取消订阅吗?
【发布时间】:2021-06-19 22:03:29
【问题描述】:

在 rxjs 中,如果调用了complete 方法,我应该也调用 unsubscribe 吗?

例如,我有一个来自 rxjstimer,我设置为 5 秒。

在调用订阅函数后,我是否也应该从计时器中取消订阅?

import { timer } from "rxjs";

const token = timer(5 * 1000).subscribe({
  next: () => {
    console.log("xxx");

    token.unsubscribe(); // <---- should I do it to to free memory?
  },
  complete: () => {
    console.log("aaa");
  }
});

【问题讨论】:

    标签: rxjs


    【解决方案1】:

    问题:

    如果调用了complete 方法,我是否也应该调用unsubscribe

    没有。一个 observable 只能完成或出错一次。完成或出错的 observable 完成。无需退订。

    上面调用的定时器只会发出一次然后完成。除非您想取消计时器,否则无需取消订阅。如果你给计时器第二个参数,那么它会变得更像interval。然后你必须取消订阅。

    广义:

    任何短暂的 observable 都会自行完成。使用offrom(array) 创建的promise、HTTP 调用、可观察对象就是这种情况。除非某些业务逻辑另有规定,否则这些通常不需要取消订阅。

    长期存在的 observable 不会自行完成,必须以某种方式进行管理。用户交互往往没有定义的结束(想想像按钮点击这样的 DOM 事件)。 intervals 也没有定义结束。

    如何退订

    最好的解决方案是使用代表您处理订阅/取消订阅的运营商。在最好的情况下,它们不需要额外的认知负荷,并且在更奇特的情况下能够相对较好地控制/管理错误(远距离的怪异动作较少)。

    大多数高阶运算符都这样做(concat、merge、concatMap、switchMap、mergeMap 等)。 take、takeUntil、takeWhile 等其他运算符让您可以使用更具声明性的样式来管理订阅。

    在可能的情况下,这些更可取,因为它们都不太可能在使用它们的团队中引起奇怪的错误或混乱。

    【讨论】:

      【解决方案2】:

      当然你应该取消订阅,只需在控制台日志中查看token。它有道具:closed: true, _subscriptions: null, isStopped: true

      如果没有取消订阅,请比较: closed: false isStopped: false _subscriptions: Array[1].

      如果您想要完整的值,您必须填写您的 Subject,在这种情况下 - timer

      【讨论】:

      • 那么如果我使用timer,我应该在调用后取消订阅吗?
      • 最好这样做,是的。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-09-30
      • 1970-01-01
      • 2019-03-06
      • 2019-03-16
      • 2019-10-25
      • 1970-01-01
      • 2018-07-29
      相关资源
      最近更新 更多