可观察对象、响应式编程和遗憾

2025-05-26

可观察对象、响应式编程和遗憾

截至撰写本文时,我已经在RxJS 项目上工作了将近六年。刚开始的时候,我完全不知道自己在做什么(如果没有 Paul Taylor 和其他人,我肯定不可能发布那些最初的版本)。我还记得自己当时在 npm 上查看每周的下载量,就能算出其中到底有多少是我的。快进到今天,RxJS 和可观察对象已经变得非常流行……很多人喜欢,也有人讨厌,而我担心的是,大多数人都误解了它们。

可观察对象、响应式编程和 RxJS

我现在看到的一个大问题是,无论好坏,可观察对象现在都与 RxJS 紧密相关。回想起来,我真希望我们当初把Observable原语单独发布成一个包,把操作符也放在另一个包里。

当这项工作开始时,我天真地乐观地认为它会进入 ECMAScript 标准,而 RxJS 只会“变成一堆辅助函数的集合”,就像我之前说的那样。但几年过去了,TC39 提案停滞不前。最终,世界是通过 RxJSObservable了解它的。Observable

Observable 不是 RxJS。Observable 不需要“操作符”。它们是原语。是 的“对偶” Iterable。一种简单的基于推送的类型。仅此而已。

响应式编程不一定是可观察的。响应式编程是一种范式或实践。它可以用函数、Promise 等来实现。本质上,如果你能将代码划分成函数,让它们在不知道任何来源的情况下对传入事件做出“反应”,那么恭喜你,你就是“响应式”的。

RxJS 是一个围绕可观察对象构建的函数库,而不是反过来。可观察对象可以独立于RxJS 而存在。它们也出现在其他库中,通常形式略有不同,但总体概念是相同的。Facebook的 Relay 有一个内部的可观察对象实现,与 RxJS 的实现惊人地相似。事实上,我已经记不清有多少次见过这样的抽象,它相当于一个接口,接受一个回调来处理多个值、一个错误或一个完成,并返回或使用某种取消语义。

遗憾

1. 庞大的 API

RxJS 5 从 RxJS 4 及更低版本继承了其庞大的API 接口。而 RxJS 4 及更低版本又从 RxNET 继承了 API,而且是很多年前的事了。许多 API 甚至有人认为“不必要”,但之所以存在,是因为“它们一直存在,而且必须一直存在”。RxJS 5 或许是我们在这个库的历史上唯一一次真正精简 API 的机会。我们确实做了一些,但可能还不够。庞大的 API 接口在社区中引发了困惑和不满。在我看来,这一切都是可以理解的。

2. RxJS 超越 Observable

Observable 本身从来就没有机会展现自己的光芒。在我看来,RxJS 真正的优势在于Observable类型本身,而不是操作符。那些操作符只是些用来做一些很酷事情的花招。拥有一个像 RxJS 这样带有保证的惰性类型Observable才是真正的亮点。

Observable将获得以下保证:

  1. 一旦完成、出错或取消订阅,您将不会再收到任何消息
  2. 已注册的拆卸操作必将发生。如果您完成、出错或取消订阅,则保证会清理资源。
  3. 统一的 API 可以表示各种各样的事物:事件、多个值、单个值、用户交互、流数据、同步值、异步值等等。

它的设计还有其他优点。但在我看来,这些才是最大的优点。

有些人觉得 RxJS 及其所有操作符都和可观察对象密不可分。这真是令人遗憾。RxJSObservable很简单,一个非常简单的类型。而 RxJS 却因其庞大的 API 和奇怪的名称而变得复杂。

3. 我们从未真正概述过 RxJS 最适合哪些用户

免责声明:以上仅代表我个人对 RxJS/Observable 使用的看法,不代表 RxJS 核心团队的观点。您可以随意使用 RxJS 或其他任何库,只要您觉得合适即可。只要代码有效,您可以维护它,测试它,在我看来,它就是好代码。结束。

简而言之,一旦人们接触到 RxJS,它就是一项令人兴奋的技术。它会突然间被应用于方方面面。公平地说,这种心态在很多库和框架的技术中都存在。但我认为,对于 RxJS 来说,这种心态会变得阴险,损害 RxJS 社区的利益。

例子:

  • 你有一个按钮,点击后会获取最新数据并显示出来。你需要完整的 RxJS 吗?不,可能不需要。“但是取消怎么办???” ……你想要一个可观察的,而不是操作符。你可以在这里使用 RxJS 来Observable实现,但我建议不要直接使用concatMapet al 。尤其是在你的团队不习惯使用 RxJS 的情况下。但这并不意味着你不应该使用Observable。事实上,你或许应该使用 。

  • 你有通过 Web Socket 传输的流数据,你需要将其拆分成几个不同的流,并更新 UI 的两个部分。没错!这就是 RxJS 的用途。你filter离一个可靠的用例只差一个操作符了。

  • 即使使用返回 Promise 的 API,您也遇到了复杂的异步协调和/或竞争条件?说实话,您可能也想在这里使用 RxJS,因为它提供了Observable、以及类似的实用运算符concatMap,可以保证顺序等,并且和具有完整的互操作性async/awaitPromise

4. 我们从未教过人们如何使用 RxJS 编写可读的代码

我们把强大的工具交给人们,然后让他们自己动手。没有提供任何指导或经验,教他们如何有效地使用图书馆,以免把同事逼疯。这就像拿到一套没有说明书的电动工具。你该如何保养它?如何解决问题?工具该放在哪里?等等。

这样做的结果是,人们写的代码在重新审视时变得难以理解。最令人吃惊的是,一些工程师,他们通常都很理性,却宣称 RxJS “不可读”,就好像无论他们怎么努力,都无法让代码变得可读一样。在我看来,这简直是失败主义。和其他任何事情一样,阅读和组织 RxJS 代码的良好实践和策略是可以学习和教授的。但我知道,我个人在传播这方面的知识方面做得还不够。

结果

总体而言,我认为大家对 RxJS 的反响非常积极。社区已经组织了一次会议。我看到很多社区(不仅仅是 Angular)都在讨论它。而且它的使用率也在稳步增长。

但反过来想,RxJS 和 Observable 的声誉也受到了损害,这源于人们对 Observable 和 RxJS 的误解,以及对这个库的普遍滥用,在我看来。一些知名科技人士甚至高呼“真希望 RxJS 不存在”。我担心,如果这种想法蔓延开来,RxJSObservable本身就会走向毁灭。说实话,这将是最大的耻辱。

本身Observable就是一个巨大的胜利。正如我上面所说,它是一个原语,以多种形式出现在许多地方,我认为它应该在语言中占有一席之地,就像Iterable和 一样Promise。在我看来,人们对 RxJS 的 API 感到厌恶和/或滥用和误用是完全可以理解的。

RxJS 的某些部分我并不喜欢,而且我无法快速调整这个库,因为它太流行了,很容易让太多人失望。但我最喜欢的部分,也就是 RxJSObservable本身,以及它提供的保证,却面临着被某些人弃之不顾的危险。在我看来,这真是太悲惨了。

前进的道路

就我而言,我计划继续倡导促进人们对 RxJS 和 Observable 的“何时/何地/为何”的理解。我希望更好地区分 Observable 和 RxJS。我还想努力简化 RxJS API:精简 API,移除不必要的部分,改进文档和可读性,为用户提供更多关于如何使代码更易于维护的指导等等。

别误会,我对 RxJS 目前的情况还有其他遗憾,但我相信随着时间的推移,我们能够弥补所有这些不足。我最担心的是,仍然有很多人不了解 RxJS 的Observable原始特性及其优势,因为他们把它和 RxJS 联系在一起,并且由于学习难度较高而不愿尝试。

文章来源:https://dev.to/rxjs/observables-reactive-programming-and-regret-4jm6
PREV
你可能不知道的 10 个 Web 开发 YouTube 频道 Coding Addict dcode codeSTACKr Drew Ryan Codevolution 在线教程 Code Explained Ania Kubów 关注 Andrew Tyler Moore
NEXT
npm7 公告