.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 更新

【讨论】:

嗨@mar​​tin 确实需要(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

Angular4最佳实践之unsubscribe

mqtt协议-broker之moqutte源码研究五之UNSUBSCRIBE与DISCONN报文处理

unsubscribe 不是 observable 上的函数

XMPP 客户端对 <presence type=unsubscribed...> 节的正确响应是啥?