31、Scheduler (调度器)
RxJS 中的调度器 ( Schedulers ) 是用来控制事件发出的顺序和速度的(发送给观察者的)。
const a$ = Rx.Observable.of(1, 2);
const b$ = Rx.Observable.of(10);
const c$ = Rx.Observable.combineLatest(a$, b$, (a, b) => a + b);
c$.subscribe(c => console.log(c));
默认情况下,RxJS 使用所谓的递归调度器。下面是它的工作原理:
- c$ 被订阅
- combineLatest 的第一个输入流 a$ 被订阅
- a$ 发出值 1
- combineLatest 将 1 作为 a$ 的最新值进行保存
- a$ 发出值 2
- combineLatest 将 2 作为 a$ 的最新值进行保存
- combineLatest 的第二个输入流 b$ 被订阅
- b$ 发出值 10
- combineLatest 将 10 作为 b$ 的最新值进行保存
- combineLatest 现在同时拥有了 a$ 和 b$ 的值,因此它发出值 2 + 10
发出的顺序为 1, 2, 10。
咱们在 a$ 上使用 asap 调度器来让其“慢下来”:
const a$ = Rx.Observable.from([1, 2], Rx.Scheduler.asap); // 新代码
const b$ = Rx.Observable.of(10);
const c$ = Rx.Observable.combineLatest(a$, b$, (a, b) => a + b);
c$.subscribe(c => console.log(c))
- c$ 被订阅
- combineLatest 的第一个输入流 a$ 被订阅
- combineLatest 的第二个输入流 b$ 被订阅
- b$ 发出值 10
- combineLatest 将 10 作为 b$ 的最新值进行保存
- a$ 发出值 1
- combineLatest 将 1 作为 a$ 的最新值进行保存
- combineLatest 现在同时拥有了 a$ 和 b$ 的值,因此它发出值 1 + 10
- a$ 发出值 2
- combineLatest 将 2 作为 a$ 的最新值进行保存
- combineLatest 发出值 2 + 10
发出的顺序为 10, 1, 2。
咱们可以为 b$ 也自定义调度器:
const a$ = Rx.Observable.from([1, 2], Rx.Scheduler.asap);
const b$ = Rx.Observable.from([10], Rx.Scheduler.asap); // 新代码
const c$ = Rx.Observable.combineLatest(a$, b$, (a, b) => a + b);
c$.subscribe(c => console.log(c));
- c$ 被订阅
- combineLatest 的第一个输入流 a$ 被订阅
- combineLatest 的第二个输入流 b$ 被订阅
- a$ 发出值 1
- combineLatest 将 1 作为 a$ 的最新值进行保存
- b$ 发出值 10
- combineLatest 将 10 作为 b$ 的最新值进行保存
- combineLatest 现在同时拥有了 a$ 和 b$ 的值,因此它发出值 1 + 10
- a$ 发出值 2
- combineLatest 将 2 作为 a$ 的最新值进行保存
- combineLatest 发出值 2 + 10
发出的顺序为 1, 10, 2。
调度器还可以让事件的发出变得更快,同时保持发出的顺序不变。例如,RxJS 的 TestScheduler
可以使 Observable.interval(1000).take(10)
被订阅时进行同步执行,而不需要花费10秒钟来完成:
Rx.Observable.interval(1000, new Rx.TestScheduler()).take(10)
31、Scheduler 调度器类型
调度器 | 目的 |
---|---|
null | 不传递任何调度器的话,会以同步递归的方式发送通知。用于定时操作或尾递归操作。 |
Rx.Scheduler.queue | 当前事件帧中的队列调度(蹦床调度器)。用于迭代操作。 |
Rx.Scheduler.asap | 微任务的队列调度,它使用可用的最快速的传输机制,比如 Node.js 的 process.nextTick() 或 Web Worker 的 MessageChannel 或 setTimeout 或其他。用于异步转换。 |
Rx.Scheduler.async | 使用 setInterval 的调度。用于基于时间的操作符。 |
这是官网给出的类型,大家看看就行。
32、Scheduler 调度器的使用
对于返回有限和少量消息的 observable 的操作符,RxJS 不使用调度器,即 null 或 undefined 。对于返回潜在大量的或无限数量的消息的操作符,使用 queue 调度器。对于使用定时器的操作符,使用 asap或aysnc 调度器。
静态创建操作符通常可以接收调度器作为参数。
使用 subscribeOn 来调度 subscribe() 调用在什么样的上下文中执行。
使用 observeOn 来调度