RxJS: Don’t Unsubscribe

2024-05-31 13:58
文章标签 rxjs unsubscribe

本文主要是介绍RxJS: Don’t Unsubscribe,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

RxJS: Don’t Unsubscribe

Well… okay, just don’t unsubscribe quite so much.

I’m often enlisted to help someone debug an issue with their RxJS code or figure out how to structure an app that is composing a lot of async with RxJS. When doing so, I generally see the same thing pop up over and over again, people keeping handles to tons and tons of subscription objects. Developers will invariably make 3 HTTP requests with an Observable, and then keep 3 subscription objects that they’re going to call when some event occurs.

I can see how it would happen. People are used to using `addEventListener` N times, and then having some clean up where they have to call `removeEventListener` N times. It feels natural to do the same with subscription objects, and for the most part you’re right. But there are better ways. Keeping too many subscription objects around is a sign you’re managing your subscriptions imperatively, and not taking advantage of the power of Rx.

What imperative subscription management looks like

Take for example this make-believe component (I’ll purposely make this non-React and non-Angular and somewhat generic):

In the example above, you can see I’m manually calling `unsubscribe` on three subscription objects I’m managing myself in the `onUnmount()` method. I’m also calling `this.dataSub.unsubscribe()` when someone clicks the cancel button on line #15, and again on line #22 when the user sets the range selector above 500, which is some threshold at which I want to stop the data stream. (I don’t know why, it’s a weird component)

The ugliness here is I’m imperatively managing unsubscriptions in multiple places in this fairly trivial example.

The only real advantage to using this approach would be performance. Since you’re using fewer abstractions to get the job done, it’s likely to perform a little better. This is unlikely to have a noticeable effect in the majority of web applications however, and I don’t think it’s worth worrying about.

Alternatively, you can always combine subscriptions into a single subscription by creating a parent subscription and adding all of the others like children. But at the end of the day, you’re still doing the same thing, and you’re probably missing out.

Compose your subscription management with takeUntil

Now let’s do the same basic example, only we’ll use the `takeUntil` operator from RxJS:

The first thing you might notice is it’s less code. That’s just one benefit. Another thing that’s happened here is I have composed a stream of `stop$` events that kill the data stream. That means when I decide I want to add another condition to kill the data stream, like say a timer, I can simply merge a new observable into `stop$`. Another thing that is readily apparent is I only have one subscription object that I’m managing imperatively. There’s no way around this, because this is where your functional programming is meeting your object-oriented world. JavaScript is an imperative language after all, and we have to meet the rest of the world half way at some point.

Another advantage to this approach is it actually completes the observable. That means there’s a completion event that can be handled anytime you want to kill your observable. If you just call `unsubscribe` on a returned subscription object, there’s no way you’ll be notified that the unsubscription happened. However if you use `takeUntil` (or others listed below), you will be notified the observable has stopped via your completion handler.

The last advantage I’ll point out is the fact that you’re actually “wiring everything up” by calling `subscribe` in one place, this is advantageous because with discipline it becomes much, much easier to locate where you’re starting your subscriptions in your code. Remember, observables don’t do anything until you subscribe to them, so the point of subscription is an important piece of code.

There is one disadvantage here in terms of RxJS semantics, but it’s barely worth worrying about in the face of the other advantages. The semantic disadvantage is that completing an observable is a sign that the producer wants to tell the consumer it’s done, where unsubscribing is the consumer telling the producer it no longer cares about the data.

There will also be a very slight performance difference between this and just calling `unsubscribe` imperatively. However, it’s unlikely that the perf hit will be anything noticeable in the mass-majority of applications.

Other operators

There are many other ways to kill a stream in a more “Rx-y” way. I’d recommend checking out the following operators at the very least:

  • take(n): emits N values before stopping the observable.
  • takeWhile(predicate): tests the emitted values against a predicate, if it returns `false`, it will complete.
  • first(): emits the first value and completes.
  • first(predicate): checks each value against a predicate function, if it returns `true`, the emits that value and completes.
Summary: Use takeUntil, takeWhile, et al.

You should probably be using operators like `takeUntil` to manage your RxJS subscriptions. As a rule of thumb, if you see two or more subscriptions being managed in a single component, you should wonder if you could be composing those better.

  • more composeable
  • fires a completion event when you kill your stream
  • generally less code
  • less to manage
  • fewer actual points of subscription (because fewer calls to `subscribe`)
Reference:https://medium.com/@benlesh/rxjs-dont-unsubscribe-6753ed4fda87#.ct6gdyavc

这篇关于RxJS: Don’t Unsubscribe的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1018124

相关文章

error TS2307: Cannot find module 'rxjs-compat/Subject'.

新导的angular项目   ng serve 报错: ERROR in node_modules/rxjs/Subject.d.ts(1,15): error TS2307: Cannot find module 'rxjs-compat/Subject'. src/app/services/event.service.ts(2,10): error TS2305: Module '"C:/U

跟我一起学Angular ---RxJS

跟我一起学Angular —RxJS RxJS 针对 异步数据流的编程 几种方法 1,回调函数 2,事件监听/发布订阅 3,Promise 4,Rxjs Rxjs 语法类似 Promise 先定义服务 import { Observable } from ‘rxjs’; ///Rxjs 比 Promise 更强大。可以多次执行,可以取消 Promise 不可以 getInterValJxj

npm install 卡在reify:rxjs: timing reifyNode的解决办法

今天要逆向跑一个electron,但是npm install一直卡在 reify:element-plus: timing reifyNode:node_modules/lodash Completed in 6664ms 这里一动不动,一番研究之后发现可能跟用的镜像有关系,我原本是官方镜像,总感觉第三方镜像有一些莫名的问题,然后之前迫不得已换到淘宝镜像,最后从淘宝镜像切换到官方就好了。

【Rxjs】实例讲解zip和combineLatest操作符的区别

最近因为要改一个bug, 开始死磕RxJS, 这个东西理解起来是真复杂啊,不过经过四天的战斗,终于搞好了bug。 有个想法是接下来写一写RxJS的系列知识。这篇算是一个开头吧。如果出了系列文章,会按照顺序再排版的,在之前添加上一些概念的通俗解释。如果你们已经对RxJS有了认知,就想知道zip和combineLatest的区别,那么直接往下看吧。 一 应用场景 假设我们有两个input输入框,

MQTT 5.0 报文解析 03:SUBSCRIBE 与 UNSUBSCRIBE

欢迎阅读 MQTT 5.0 报文系列 的第三篇文章。在上一篇中,我们介绍了 MQTT 5.0 的 PUBLISH 及其响应报文。现在,我们将介绍用于订阅和取消订阅的控制报文。 在 MQTT 中,SUBSCRIBE 报文用于发起订阅请求,SUBACK 报文用于返回订阅结果。而 UNSUBSCRIBE 和 UNSUBACK 报文则在取消订阅时使用。相比于取消订阅,订阅操作更加常用。不过在本文中,我们

像呼吸一样自然:React hooks + RxJS

像呼吸一样自然:React hooks + RxJS   上个月的 React Conf 上,React 核心团队首次将 hooks 带到的公众们的眼前。起初我看到这样奇怪的东西,对它是很抗拒的。Dan 说 JavaScript 里的 this 太黑了,从其他语言转来写 React 的人会很不适应。然而 hooks 本质上也是一种黑魔法,需要理解它的本质依旧需要对 JS 的各种闭包和作用域的问

ES6 rxjs Observable

一、拉取(Pull)  、 推送(Push) 介绍 Observable 之前,要先了解两个设计模式: Observer Pattern - (观察者模式) Iterator Pattern - (迭代器模式) 这两个模式是 Observable 的基础。 Observable(可观察对象)是基于推送(Push)运行时执行(lazy)的多值集合。下方表格对Observab

ReactiveX生态系统RxJava RxJS Rx.NET RxCpp RxGo RxSwift RxPHP

ReactiveX是一个库,用于使用可观察序列组合异步和基于事件的程序。 它扩展了observer模式,以支持数据和/或事件的序列,并添加了操作符,允许您以声明的方式组合序列,同时抽象出底层线程、同步、线程安全、并发数据结构和非阻塞I/O等问题。 Languages Java: RxJavaJavaScript: RxJSC#: Rx.NETC#(Unity): UniRxScala: Rx

浅谈RxJS WebSocket

RxJS WebSocket是一个强大的库,使开发人员更容易在Web应用程序中使用WebSocket。当与Angular结合使用时,RxJS WebSocket可以帮助简化前端和后端系统之间实时连接的创建和维护。 什么是WebSocket? WebSocket是一种通信协议,它允许客户端和服务器通过单个TCP连接进行双向数据交换。与遵循请求-响应模型的HTTP不同,WebSocket提供了一个

Angular系列教程之观察者模式和RxJS

文章目录 引言RxJS简介RxJS中的设计模式观察者模式迭代器模式 示例代码RxJS 在 Angular 中的应用总结 引言 在Angular开发中,我们经常需要处理异步操作,例如从后端获取数据或与用户的交互。为了更好地管理这些异步操作,Angular中引入了RxJS(响应式编程库),它基于观察者模式提供了一种优雅的解决方案。本文将介绍RxJS的基本概念和使用方法,并附上示例代