RxJS 是什么
依照 RxJS 的官方定义,
RxJS 是使用 Observables 的响应式编程的库,它使编写异步或基于回调的代码更容易。
针对 JavaScript 中的非阻塞行为(non-blocking manner),RxJS in Action(Deniels, P.P etc.)列举了 3 种处理方式,包括回调函数(callback functions)、事件派发器(Event Emitters)以及Promise。RxJS 则提出了一种新的思维方式:数据流,基于数据流来处理 JavaScript 中的异步或回调函数。举个例子,监听按钮点击事件,我们通常的处理方式是:
const button = document.querySelector('button');
button.addEventListener('click', () => {
/** code **/
});
基于 RxJS 的处理方式是:
const button = document.querySelector('button');
const subscription = fromEvent(button, 'click').subscribe(() => {
/** code **/
});
从表面上看,操作符fromEvent和函数addEventListener做一样的事,能够达到一样的效果,似乎看不出来 RxJS 的优势在何处?RxJS in Action 提到了一句话:
The concept of a stream can be applied to any data point that holds a value; this ranges from a single integer to bytes of data received from a remote HTTP call.
不管是鼠标点击、键盘输入、触摸手势,还是 HTTP 请求发送,乃至于简单的数字处理,RxJS 均将其视为数据流,通过对数据源的订阅和操作,处理异步任务。所谓万物皆可数据流,不外如是。如果你从未接触过 RxJS,可能无法体会到这句话的美妙之处,但等你熟练使用 RxJS 来编写自己的代码后,回过头来,相信你会有更深的理解。
接下来,我们进入正题,RxJS 源代码学习之路。RxJS 官方文档罗列了几个核心概念,分别是:
- Observable (可观察对象): 表示一个概念,这个概念是一个可调用的未来值或事件的集合。
- Observer (观察者): 一个回调函数的集合,它知道如何去监听由 Observable 提供的值。
- Subscription (订阅): 表示 Observable 的执行,主要用于取消 Observable 的执行。
- Operators (操作符): 采用函数式编程风格的纯函数 (pure function),使用像
map、filter、concat、flatMap等这样的操作符来处理集合。- Subject (主体): 相当于 EventEmitter,并且是将值或事件多路推送给多个 Observer 的唯一方式。
- Schedulers (调度器): 用来控制并发并且是中央集权的调度员,允许我们在发生计算时进行协调,例如
setTimeout或requestAnimationFrame或其他。
除此之外,其源代码中还向外暴露了 Utils 和 Notification,具体内容我们会在后面的学习中慢慢接触到。接下来,我们首先来学习 RxJS 框架中核心的核心——Observable。
代码调试
学习源代码,不可避免地需要调试源代码,帮助我们理解个中设计。第一步,从 Github 获取 RxJS 框架源代码:
$ git clone https://github.com/ReactiveX/rxjs.git
接下来,按照官方文档指示,执行第三方库安装 & 代码编译:
$ yarn install
$ yarn compile
到此,RxJS 本地库编译完毕,我们需要想办法将其引入到自己的测试项目中。我们可以通过一些基础的手段创建一个简单的测试项目:
$ mkdir rxjs-learning && cd rxjs-learning
$ npm init
$ yarn add typescript ts-mode
$ npx tsc --init # 创建 tsconfig.js
$ mkdir src && touch src/index.ts
而后,修改 package.json:
{
"name": "rxjs-learning",
"version": "1.0.0",
"description": "",
"main": "index.ts",
"scripts": {
"test": "echo "Error: no test specified" && exit 1",
"playground": "./node_modules/.bin/ts-node src/index.ts"
},
"author": "",
"license": "ISC",
"dependencies": {
"rxjs": "^7.1.0",
"ts-node": "^10.0.0",
"typescript": "^4.3.4"
}
}
由此,我们可以通过运行:
yarn playground
来执行 src/index.ts 中的代码。如上,创建自定义测试项目的方法并不重要,重要的是我们需要将 RxJS 编译好的代码链接到自己的项目中,因此:
$ cd rxjs && yarn link
完成之后,打开自己的项目:
$ cd rxjs-learning && yarn link rxjs
至此,本地 RxJS 代码将会替代 ./node_modules/rxjs 运行,快来试试吧!接下来,我们将首先学习 RxJS 的 Obsevable 模块,参见 RxJS 源代码学习(二)—— Observable (juejin.cn)。