📜  RxJS-使用调度程序(1)

📅  最后修改于: 2023-12-03 14:47:11.183000             🧑  作者: Mango

RxJS-使用调度程序

RxJS 是一种响应式编程范式的库,通过 RxJS 我们可以方便的处理异步事件、处理流事件等,提高了前端开发的效率和代码质量。而调度程序是 RxJS 中的一种重要组件,可以让我们更好地控制事件的执行。

调度程序是什么

调度程序是 RxJS 中的一种执行上下文,通俗的说就是指定某个事件的执行方式和时机。在 RxJS 中调度程序有多个选项,每个选项代表不同的执行上下文。

RxJS 内置调度程序

RxJS 内置了许多常用的调度程序,下面是常用的几个调度程序:

  • asap:尽快地在当前的执行上下文中执行事件,优先级高于 setTimeout,但是优先级低于 animationFrame。
  • queue:按照顺序在当前的执行上下文中执行事件。
  • animationFrame:在下一个 animationFrame 时执行事件,适用于需要优化性能和防抖的事件。
  • interval:按照指定的时间间隔来执行事件。
  • timer:在指定的时间后执行事件。
使用调度程序

在 RxJS 中,我们可以通过使用 observeOnsubscribeOn 方法来指定事件的执行上下文。

observeOn

observeOn 方法用于指定事件在何时执行,例如下面的代码指定事件在下一个 animationFrame 时执行:

import { fromEvent } from 'rxjs';
import { observeOn } from 'rxjs/operators';

// 获取按钮元素
const button = document.querySelector('#button');

// 订阅点击事件,使用 observeOn 来指定在下一个 animationFrame 时执行
fromEvent(button, 'click')
  .pipe(observeOn(animationFrame))
  .subscribe(() => console.log('clicked'));

subscribeOn

subscribeOn 方法用于指定事件在何处执行,例如下面的代码指定事件在线程中执行:

import { fromEvent } from 'rxjs';
import { subscribeOn } from 'rxjs/operators';

// 获取按钮元素
const button = document.querySelector('#button');

// 订阅点击事件,使用 subscribeOn 来指定在线程中执行
fromEvent(button, 'click')
  .pipe(subscribeOn(thread))
  .subscribe(() => console.log('clicked'));

在这个例子中,我们将按钮点击事件订阅放到了一个线程中执行,这样就不会阻塞主线程的执行。

自定义调度程序

除了使用内置的调度程序之外,我们还可以自定义一个调度程序。下面的例子是自定义一个调度程序的例子:

import { Scheduler } from 'rxjs/internal/Scheduler';
import { Observable } from 'rxjs/internal/Observable';
import { asap } from 'rxjs/internal/scheduler/asap';

// 自定义调度程序
const newScheduler = new Scheduler((work, delay = 0) => {
  const task = () => {
    if (delay === 0) {
      work();
    } else {
      setTimeout(() => work(), delay);
    }
  }
  task();
  return { unsubscribe: () => {} };
});

// 使用自定义调度程序
Observable.create((observer) => {
    observer.next(1);
    observer.next(2);
    observer.complete();
  })
  .subscribeOn(newScheduler)
  .subscribe({
    next: value => console.log(value),
    complete: () => console.log('complete')
  });

在这个例子中,我们传入一个函数和一个延迟值来定义任务。任务可以是同步或异步的,如果延迟为 0 就是同步任务,否则就是异步任务。

最后通过 subscribeOn 方法指定事件在自定义调度程序中执行。