rxjs - 每次订阅都需要退订吗
问题描述
我正在尝试确定如何处理以下代码
let sub = myObservable.subscribe(
v => doThing(v),
e => handle(e),
() => sub.unsubscribe(),
)
问题是 1. 此代码不正确,因为 myObservable 同步完成,完成时会抛出 NPE。2. 尽管我怀疑这里的取消订阅呼叫是一个好习惯。我不禁觉得这可能没有必要,因为我在其他任何地方都没有看到它完成。
我已经阅读了这篇文章https://blog.angularindepth.com/why-you-have-to-unsubscribe-from-observable-92502d5639d0但它实际上让我比开始时更加困惑。
如果我做
let subA = myObservable.pipe(take(1)).subscribe()
let subB = myObservable.pipe(takeUntil(foo)).subscribe()
我不再需要取消订阅 subA 和 subB 了吗?
这里的 subC 怎么样?
let subC = myObservable.pipe(finalize(() => cleanupOtherResources())).subscribe()
或者我是否必须将所有订阅添加到每个调用subscribe()
任何类的列表中BehaviorSubject
并立即取消订阅?
谢谢!
解决方案
退订始终是最佳做法。如果您知道您的类的 clean up 方法实际上是在可观察到的 cleanup 上发出的,那么 takeUntil 就可以使用。take 并不总是保证 observable 已经发出。在某些情况下,您知道 observable 肯定会至少发出一次,但仍有可能造成泄漏。
假设 observable 将完成的问题是您不知道服务的内部是否返回 observable 更改。如果您假设 observable 是一个 http 请求并在请求结束时完成,那么将来将 observable 更改为缓存处理程序的重构现在已经造成内存泄漏,因为您没有取消订阅。
取消订阅还会取消任何正在进行的请求。
像这样的陈述的问题
let sub = myObservable.subscribe(
v => doThing(v),
e => handle(e),
() => sub.unsubscribe(),
)
如果 myObservable 像 BehaviorSubject 一样立即发出,那么 sub 是未定义的。我会避免像这样自行取消订阅,而是使用带有主题的 takeUntil。
const finalise$ = new Subject();
myObservable.pipe(takeUntil(finalise$)).subscribe(
v => doThing(v),
e => handle(e),
() => { finalise$.next(); },
);
此代码保证是自我退订安全的。
推荐阅读
- eclipse - 无法将远程调试器附加到 Eclipse OSGi 应用程序
- oop - 如何从 Tcl 的超类中访问派生类的成员变量?
- python - 我怎样才能让这个 twitter 机器人工作?蟒蛇 3.8
- javascript - jQuery动态添加内容到div
- interface - Java问题包含抽象、接口和异常
- c++ - 无法在类中初始化 unique_ptr 的向量
- python - 数字总和直到达到个位数
- reactjs - 带有 rxjs 错误的相关请求:可观察 {_isScalar: false, _subscribe: f}
- javascript - Express-Handlebars 部分的 Vue.js 等效项是什么?
- javascript - 以设定的时间增量循环对象