RxJS 使用调度器

17 Mar 2025 | 5 分钟阅读

什么是 RxJS 调度器?

RxJS 调度器是一种控制计时策略的方法,用于在 RxJS 应用程序或反应式应用程序中执行任务。 调度器用于控制订阅何时开始以及何时传递通知。

根据 RxJS 应用程序网站的官方文档,调度器被定义为“调度器是一种实体,使您能够定义 Observable 将在什么执行上下文中将通知传递给它的 Observer。”

一个 RxJS 调度器由以下三个部分组成

  1. 数据结构: RXJS 调度器是一种数据结构。 它知道如何根据任务的优先级或其他标准存储和排队任务。
  2. 执行上下文: RxJS 调度器是一个执行上下文。 它用于表示任务执行的位置和时间(例如:立即执行,或在另一个回调机制中执行,例如 setTimeout 或 process.nextTick,或动画帧)。
  3. 虚拟时钟: RxJS 调度器由一个虚拟时钟组成,该时钟通过调度器上的 getter 方法 now() 提供“时间”的概念。 在特定调度器上调度的任务将仅遵守该时钟指示的时间。

如何定义 RxJS 调度器?

我们知道 RxJS 调度器控制订阅必须开始时程序的执行。 我们可以通过以下方式定义一个基本的调度器。

语法

让我们看一下同步 Observable 和异步 Observable,并通过比较两者的输出来注意差异

参见同步示例

示例 1

输出

执行完以上程序后,您将看到以下结果

RxJS Working with Scheduler

参见异步示例 (通过使用调度器)

示例 2

输出

执行完以上程序后,您将看到以下结果

RxJS Working with Scheduler

示例说明

  • 您可以在上面的示例中看到,asyncScheduler 会延迟 Observable 的执行,直到同步代码运行之后。
  • async Scheduler 使用 setTimeoutsetInterval 运行。 即使延迟为零,它仍然在 setTimeout 或 setInterval 上运行。 它将在下一个事件循环迭代中运行。
  • asyncScheduler 由一个 schedule() 方法组成,该方法采用一个 delay 参数,该参数指的是根据调度器自身内部时钟的时间量。 内部时钟与实际时钟时间无关。 时间操作由调度器的时钟决定,而不是真实的时钟。
  • 这在测试中非常有用,因为我们可以轻松地设置测试时间,同时异步运行任务。

RxJS 调度器的类型

RxJS 提供了不同的调度器,可以通过使用 Scheduler 对象的静态属性来创建和返回。 让我们看看不同的调度器,并解释它们之间的区别。

RxJS 调度器可以分为以下调度器类型

索引调度器类型调度器类型的用途
1.null通过使用 null 调度器类型,通知会同步和递归地传递。 这对于恒定时间或尾递归操作很有用。
2.queueSchedulerScheduler 的 queueScheduler 类型用于在当前事件帧的队列上进行调度。 这对于迭代非常有用。
3.asapSchedulerasapScheduler 是一种调度器类型,用于在微任务队列上进行调度,该队列与用于 promise 的队列相同。
4.asyncSchedulerasyncScheduler 类型用于基于时间的操作。 此调度器类型的工作使用 setInterval 进行调度。
5.animationFrameSchedulerScheduler 的 animationFrameScheduler 类型用于调度任务,以在下一次浏览器内容重绘之前运行。 它可以用于平滑浏览器动画。

使用调度器

我们已经在 RxJS 代码中使用了调度器,而没有明确说明我们使用的调度器类型。 我们没有发现需要指定调度器的类型,因为所有处理并发的 Observable 运算符都有可选的调度器。 如果我们不提供调度器,RxJS 将自动选择一个默认调度器,使用最小并发原则。

例如

  • 如果我们使用返回具有有限且少量消息的 observable 的运算符,RxJS 不使用任何调度器,该调度器将为 null 或未定义。
  • 如果我们使用返回可能大量或无限数量消息的运算符,RxJS 将自动使用队列调度器。
  • 如果我们使用使用计时器的运算符,则 RxJS 将使用 async。

默认情况下,RxJS 使用最小并发调度器。 为了引入并发以提高性能,我们可以相应地选择不同的调度器。 要指定特定的调度器,我们可以使用那些采用调度器的运算符方法,例如,from([10, 20, 30], asyncScheduler)。

静态创建运算符通常将调度器作为参数。 例如,from(array, scheduler) 允许您指定在传递从数组转换的每个通知时要使用的调度器。 它通常是运算符的最后一个参数。

以下是采用调度器参数的静态创建运算符的列表

  • bindCallback
  • bindNodeCallback
  • combineLatest
  • concat
  • empty
  • from(从)
  • fromPromise
  • interval
  • merge
  • range
  • throw
  • timer

一些运算符还采用与时间相关的调度器参数,例如 bufferTime、debounceTime、delay、auditTime、sampleTime、throttleTime、timeInterval、timeout、timeoutWith、windowTime 等。

其他实例运算符,如 cache、combineLatest、concat、expand、merge、publishReplay、startWith 也采用调度器参数。

使用调度器,我们可以控制 Observables 发出数据的时间。 有不同种类的调度器,RxJS 会根据创建最小并发来完成工作的原则自动选择。 调度器根据它们自己的虚拟时钟运行任务。 它与现实世界的时钟无关。 许多运算符方便我们设置调度器以满足我们的需求。

简而言之,我们可以说调度器影响任务执行的计时。 我们通过传入额外的调度器参数来更改某些运算符的默认调度器。


下一主题#