关于javascript:不用一行代码搞懂React调度器原理

10次阅读

共计 1782 个字符,预计需要花费 5 分钟才能阅读完成。

大家好,我卡颂。

Scheduler(调度器)是 React 重要的组成部分。

同时,他也是个独立的包,任何 间断、可中断 的流程都能够用 Scheduler 来调度,比方:

const work = {count: 100};

function doWork(work) {
  work.count--;
  console.log('do work!')
}

work满足两个条件:

  1. 工作是间断的。一共须要执行 100 次,每次执行时调用doWork
  2. 工作是可中断的。中断复原后,接着中断前的 work.count 继续执行就行

满足这两个条件的工作都能够用 Scheduler 来调度。

调度后,Scheduler外部会生成对应task,并在正确的机会执行task.callback

const task1 = {
  // 过期工夫 等于 以后工夫 + 优先级对应工夫
  expirationTime: currentTime + priority,
  callback: doWork.bind(null, work)
}

本文会解说 Scheduler 的实现原理。晓得你不喜爱看大段的代码,所以本文没有一行代码。文末有 Scheduler 的源码地址,感兴趣的话能够去看看。

开整~

工作流程概览

Scheduler的工作原理如下图,接下来会具体解释:

Scheduler 中有两个容易混同的概念:

  1. delay

delay代表 task 须要提早执行的工夫。配置了delaytask会先进入 timerQueue 中。

delay 对应工夫到期后,该 task 会转移到 taskQueue 中。

  1. expirationTime

expirationTime代表task 的过期工夫

不是所有 task 都会配置 delay,没有配置delaytask会间接进入 taskQueue。这就导致taskQueue 中可能存在多个task

如何决定哪个 task.callback 先执行呢?Scheduler依据 task.expirationTime 作为排序根据,值越小优先级越高。

如果 task.expirationTime 小于以后工夫,不仅优先级最高,而且 task.callback 的执行不会被中断。

总结一下 task 的几种状况:

  1. 配置 delaydelay未到期:task肯定不会执行
  2. 配置 delay 且到期,或者未配置 delaytask,同时 task.expirationTime 未到期:依据 task.expirationTime 排序后,按程序执行
  3. task.expirationTime到期的task:优先级最高,且同步、不可中断

工作流程详解

将流程概览图替换为 Scheduler 中具体方法后,如下:

残缺工作流程如下:

  1. 执行 Scheduler.scheduleCallback 生成task

依据 是否传递 delay 参数 ,生成的task 会进入 timerQueuetaskQueue

  1. timerQueue 中第一个 task 提早的工夫到期后,执行 advanceTimers到期的 tasktimerQueue 中移到 taskQueue

其中,timerQueuetaskQueue的数据结构为 小顶堆 实现的 优先级队列

  1. 接下来,执行 requestHostCallback 办法,他会在新的 宏工作 中执行 workLoop 办法

在宏工作中执行回调 的办法很多,Scheduler在浏览器环境默认应用 MessageChannel 实现。

如果不反对 MessageChannel,会降级到setTimeoutNode老版 IE下会应用setImmediate

  1. workLoop办法会循环生产 taskQueue 中的task(即执行task.callback),直到满足如下条件之一,中断循环:
  • taskQueue中不存在task
  • 工夫切片用尽
  1. 循环中断后,如果 taskQueue 不为空,则进入步骤 3。如果 timerQueue 不为空,则进入步骤 2

总结

总结一下,Scheduler的残缺执行流程包含两个循环:

  1. taskQueue的生产(从 timerQueue 中移入或执行 scheduleCallback 生成)到生产的过程(即图中灰色局部),这是个异步循环
  2. taskQueue的具体生产过程(即 workLoop 办法的执行),这是个同步循环

如果你想理解React 中如何应用 Scheduler,能够参考 100 行代码实现 React 外围调度性能

欢送退出人类高质量前端框架群,带飞

正文完
 0