.unsubscribe 和 .take(1) 的区别
Posted
技术标签:
【中文标题】.unsubscribe 和 .take(1) 的区别【英文标题】:Difference between .unsubscribe to .take(1) 【发布时间】:2017-03-26 13:47:19 【问题描述】:我想知道,在订阅后立即使用unsubscribe
时,使用.take(1)
和.unsubscribe
在性能上是否有任何差异:
var observable = Rx.Observable.interval(100);
第一:
var subscription = observable.subscribe(function(value)
console.log(value);
).unsubscribe();
第二:
var subscription = observable.take(1).subscribe(function(value)
console.log(value);
);
对它的任何想法对性能有什么不同吗?
【问题讨论】:
var subscription = observable.subscribe(function A).unsubscribe();
将无法按预期工作,因为在 javascrit 完成执行此行后将调用函数 A。因此,如果只获得一个值,您将获得零值。建议手动订阅并使用 take(..) 或其他方法,如 take 为您处理订阅。
【参考方案1】:
每个都有不同的用途,因此很难比较它们。
一般而言,如果您采用此来源:
const source = range(1,3);
...并使用subscribe()
使用它,然后立即使用unsubscribe()
:
source.subscribe(
console.log,
undefined,
() => console.log('complete')
).unsubscribe();
... 那么来自source
的所有值都将被发出,即使我们在订阅后立即调用了unsubscribe()
。这是因为代码仍然是严格顺序(同步)的,source
是一个冷 Observable。
1
2
3
complete
顺便说一句,尝试添加delay(0)
运算符来生成source.pipe(delay(0)).subscribe(...).unsubscribe()
。这使得使用实际的setTimeout()
调用异步发出值,因此unsubscribe()
在任何next
处理程序之前被调用并被立即丢弃。
换句话说,unsubscribe()
让您随时停止接收值。即使源没有发出任何值(我们从未收到任何完整的通知)。
使用take()
运算符将链限制为仅发出特定数量的值。
source.pipe(
take(1),
)
.subscribe(
console.log,
undefined,
() => console.log('complete')
);
这只是发出一个值并完成:
1
complete
即使添加.unsubscribe()
,结果也是一样的。
观看现场演示:https://stackblitz.com/edit/rxjs-tbu5kb
所以take()
是一个运算符,而unsubscribe()
是Subscription
对象上的一个方法。这两件事通常可以互换,但它们永远不会完全相互替代。
2019 年 1 月:针对 RxJS 6 更新
【讨论】:
嗨@martin 确实需要(1)取消订阅?如果我添加 take(1),我必须再次调用 unsubscribe 吗?谢谢 @fifth 不,你没有。当链完成时,它会递归调用所有处置处理程序,因此您无需自己调用unsubscribe
。
第五,@martin - 你能从这两个 cmets 中提问和回答吗?我实际上是在寻找这个特定的问题(“take-1 是否取消订阅?”)并意外地进入了这个问题。从您的 cmets 上异常多的赞成票来看,其他人似乎同意 ;) 或者至少以某种可见的方式将其添加/插入到当前的问答中。 take-X(或任何“完成”流)确实取消订阅这一事实非常重要,我找不到任何能触及这个问题并给出明确而明确的答案的问答,就像马丁在这里的评论一样。
@quetzalcoatl 如果您看到源代码,它会调用取消订阅。 github.com/ReactiveX/rxjs/blob/master/src/internal/operators/…
小心,如果由于某种原因它没有占用一个(或任何数量的计数),它不会取消订阅。【参考方案2】:
请记住,take(1) 仍然不会取消订阅 组件正在被销毁。订阅一直有效,直到 无论组件是活动的还是被破坏的,都会发出第一个值。 所以如果我们做一些更疯狂的事情,比如访问 DOM,在我们的 订阅 — 我们最终可能会在控制台中出现错误。
https://medium.com/angular-in-depth/the-best-way-to-unsubscribe-rxjs-observable-in-the-angular-applications-d8f9aa42f6a0
【讨论】:
以上是关于.unsubscribe 和 .take(1) 的区别的主要内容,如果未能解决你的问题,请参考以下文章
subscription.unsubscribe() 和 subscription.remove() 有啥区别?
如何使用 React hooks 和 Redux 从 useEffect 执行 store.unsubscribe
mqtt协议-broker之moqutte源码研究五之UNSUBSCRIBE与DISCONN报文处理