1.RxJS简介
1.1 Reactive extension
RxJS 是一个库,它通过使用可观察的序列来编写异步任务和基于事件的JavaScript库。它提供了一个核心类型 Observable,附属类型 (Observer、 Schedulers、 Subjects) 和受 Array的方法启发的操作符 (map、filter、reduce、every等等),这些数组操作符可以把异步事件作为集合来处理。
1.2 ReactiveX
RxJS 结合了 观察者模式、迭代器模式和使用集合的函数式编程,以满足以一种理想方式来管理事件序列所需要的一切。
可以把 RxJS 当做是用来处理事件的 Lodash
2.RxJS的核心概念
RxJS 中用来处理异步事件的基本概念:
2.1 Observable (可观察的对象): 表示一个概念,代表未来即将产生的可观察的对象。RxJS创建Observable的API有from,range,interval,fromEvent等等。Observable在执行的过程中会发送error,next,complete通知给Observer。
2.2 Observer (观察者): 一个回调函数的集合,它知道如何去监听由 Observable 提供的值,观察者,用来观察可观察的对象,接收可观察对象的数据,包含三个回调函数:error,next,complete。
2.3 Subscription (订阅): 建立Observable和Observer的订阅关系,返回一个Subscription对象,表示可清理的资源对象,也表示 Observable 的执行,执行之后清理或用于取消 Observable 的执行,即 unsubscribe。(如果有2个subscription A和B,可以将B add到A里,然后A.unsubscribe就可以取消两个subscription)。
2.4 Operators (操作符): 操作符,采用函数式编程风格的纯函数 (pure function),主要用来处理一系列的可观察对象(Observable),简而言之就是处理Observable数据并返回新的Observable。常用的操作符有:take, map,filter,concatAll等。Operators的设计灵感来自数组Array的方法(map,filter,concat等)。
2.5 Subject (主体): 相当于 EventEmitter,并且是将值或事件多路推送给多个 Observer 的唯一方式。Subject 是一种特殊类型的 Observable,同时它也是Observer,它允许将值或事件多播给多个观察者,所以 Subject 是多播的(1对多的广播,可以看做Broadcast),而普通的 Observables是单播的(每个已订阅的观察者都拥有 Observable 的独立执行)。
2.6 Schedulers (调度器): 是RxJS的抽象概念,实际编写过程中极少用到。它是用来控制并发并且是中央集权的调度员,允许我们在发生计算时进行协调,例如 setTimeout 或 requestAnimationFrame 或其他。
2.7 Stream (串流): 是RxJS里的抽象概念。我理解应该就是指事件流或数据流。
2.8 Pipe(管道): 是一个用来统一处理(Observable)数据的函数,函数入参传入多个操作符函数,按照传入的顺序处理Observable数据流。官方解释用它主要是为了提高代码的可阅读性。
3.RxJS 的代码怎么写
用代码示例加深对RxJS核心概念的理解
3.1 举个栗子🌰
import { interval, take } from 'rxjs';
interval(1000)
.pipe(take(4))
.subscribe((e) => console.log(e));
interval:每隔多少毫秒发送一个Observable。
pipe: 传入一个或多个操作符函数,返回新的Observable。
subscribe:传入Observer对象,接收Observable的数据,返回Subscription对象。
3.2 再举个栗子🌰🌰
import { fromEvent } from 'rxjs';
// 创建Observable, 这里是点击事件对象 Observable的命名规范是在最后加“$”符
const myClick$ = fromEvent(document, 'click');
// 创建Observer
const myObserver = {
next: (e) => {
console.log(e.clientX);
},
};
// 建立订阅关系,接收一下返回的subscription,便于后面取消订阅
const mySubs = myClick$.subscribe(myObserver);
// 取消订阅
// mySubs.unsubscribe();
RxJS的基本运行步骤
Step1:创建Observable。
Step2:创建Observer。
Step3:建立Observable和Observer的订阅关系。
注:没有Observer订阅的Observable是没有意义的。打个比方:没有粉丝的公众号是没有存在价值的。
3.3 再举个栗子🌰🌰🌰
import { take, fromEvent, filter } from 'rxjs';
// 创建Observable, 这里是点击事件对象 Observable的命名规范是在最后加“$”符
const myClick$ = fromEvent(document, 'click');
// 通过pipe传入Operator的方法,修剪Observable并返回新的Observable
const myHandleClick$ = myClick$.pipe(
take(4),
filter((ev) => ev.clientX < 300)
);
// 创建Observer
const myObserver = {
next: (e) => {
console.log(e.clientX);
},
};
// 建立订阅关系,接收一下返回的subscription,便于后面取消订阅
const handleSubs = myHandleClick$.subscribe(myObserver);
// 取消订阅
// mySubs.unsubscribe();
此处RxJS的运行步骤
Step1:创建Observable
Step2:“过滤”Observable
Step3:创建Observer
Step4:建立订阅关系
4.Operators是如何工作的?
4.1 Operators官方定义:操作符是Observable类型(对象)上的方法,本质上是一个纯函数 (pure function),它接收一个 Observable 作为输入,并生成一个新的 Observable 作为输出。订阅输出 Observable 同样会订阅输入 Observable 。
4.2 RxJS提供了哪些操作符(100+)
4.2.1 创建操作符
interval:定时发送升序的数字。传入毫秒数,每隔多少毫秒发送一个Observable,这个Observable是一个从0开始的升序的数字。
range:发送入参范围内的Observable,这个Observable是一个从第一个参数开始到第二参数结束的数字。
4.2.2 转换操作符
map:类似数组的map函数,遍历每一个Observable,转换成新的Observable。
scan:类似数组的reduce函数。
4.2.3 过滤操作符
take:只取前n个Observable。
filter:类似数组的filter函数。
4.2.4 组合操作符
concatAll:类似数组的concat函数。将多个Observable合并成一个。
merge:合并多个Observable,将它们混合在一起。
4.2.5 错误操作符
catchError:当Observable执行发生错误时,忽略错误并继续执行,生成新的Observable。
retry:当Observable执行发生错误时,重新订阅Observable并执行,执行次数由入参决定。(可用于接口请求接口)
4.2.6 工具操作符
delay:延迟输出,输入Observable,延迟多长时间输出新的Observable。
4.2.7 条件和布尔操作符
find:从第一个Observable开始,查找符合条件的Observable并返回。
4.2.8 数学和聚合操作符
max:找最大值,对比数字型Observable产生最大的新的Observable。
min:min找最小值,工作原理同max。
5.Subject是如何工作的?
5.1 Subject官方定义:Subject的作用是将Observable分发给多个Observer 。那么问题来了,Subject是如何将Observable多路广播(multicast)给Observer的呢?
举个例子🌰
import { ajax } from 'rxjs/ajax';
import { map, catchError, of, Subject } from 'rxjs';
// 创建Observable
const obs$ = ajax('https://api.github.com/users?per_page=5')
.pipe(
map((userResponse) => console.log('users: ', userResponse)),
catchError((error) => {
console.log('error: ', error);
return error;
}));
// 创建Observer
const obsever = {
next: (value) => console.log('next', value),
error: (err) => console.log('error', err),
complete: () => console.log('complete'),
};
// 创建Observer1
const obsever1 = {
next: (value) => console.log('next1', value),
error: (err) => console.log('error1', err),
complete: () => console.log('complete1'),
};
// 一对一
obs$.subscribe(obsever);
obs$.subscribe(obsever1);
// 一对多
// 创建subject
const subj = new Subject();
// 注册Obsever
subj.subscribe(obsever);
subj.subscribe(obsever1);
// 通过Obsever监听同一个Observable对象
obs$.subscribe(subj);
5.2 Subject的运行步骤
Step1:创建Observable。
Step2:创建Subject
Step3:创建1个或多个Observer
Step4:“注册”Observer
Step5:建立Observable与Subject的订阅关系。
6.附录:
RxJS GitHub: github.com/ReactiveX/r…
RxJS 中文官网:cn.rx.js.org/
RxJS 英文官网: rxjs.dev/
RxJS 练习网址:stackblitz.com/edit/rxjs?f…
RxJS Operators学习网址:reactive.how/
RxJS Operators弹珠图网址:rxviz.com/