面试官:听说你精通 React 源码,那你讲讲 Scheduler 调度器。我:😭

React Scheduler 的原理是什么,真是太简单了!根本不是你想的什么高大上的东西,50字内给你解释完。

🤖 原理

  1. 根据你传入的不同优先级创建不同过期时间的任务,根据过期时间大小放到任务队列小顶堆里面。

  2. 通过 messageChannel 安排一个宏任务执行 while 循环

    1. 拿到堆顶的任务,如果没过期或者超过 5ms 退出本次工作循环,重新安排一个宏任务,在下一帧执行。

    2. 如果过期了就开始执行这个任务,

      1. 如果任务没有返回值,这个任务就从堆中去掉,然后再拿一个堆顶的任务来执行

      2. 如果这个函数的返回值是一个函数,就退出本次的循环,这个任务保留,重新开始调度一个新的循环。

看到这里,你已经掌握 Scheduler 原理了

🚀 小贴士:小顶堆是什么?

1. 简单的扣胩,就是一棵二叉树,父节点和左右节点中,父节点永远是最小的

2. 也就是说,树顶部的节点永远是最小的,也是就是最早过期的

🤖 scheduler 在 react 中有什么用呢?

🚀 小例子:先看看这个例子

js 复制代码
function App() {
  const [name, setName] = useState('许泽川')
  
  return name
}

当我们 setName('刘德华') 在做什么呢?

  1. 其实就是创建了一个更新帮我把许泽川变成刘德华,然后触发了一个带有优先级的重渲染任务
  2. 然后呢,scheduler 就会根据这个优先级安排微任务或者宏任务来执行这个重渲染
  3. 等一下重渲染到 App 组件,其实就是重新执行 App 函数,重新执行 useState('许泽川') 在里面应用这个更新帮我把许泽川变成刘德华 到 name 上,这时候拿到 name 就是 刘德华 了

🚀 小知识:优先级是什么?

点我这里,我告诉你优先级是什么 🥰

优先级不懂的先看上面文章,不然下面的原理看不懂,顺便帮我涨涨点击率 🥰

🚀 scheduler 的用处来喽 😤

  1. 文章里提到 每次 setState 会判断当前上下文拿一个车道出来,创建一个车道对应优先级的更新,和对应优先级的重渲染任务来处理这个更新
  2. 文章里面还提到 连续事件默认事件空闲事件全部通过宏任务 MessageChannel执行重渲染任务 补充一点,就是通过 schduler 来安排宏任务的
js 复制代码
const `优先级` = `连续事件优先级 or 默认事件优先级 or 空闲事件优先级`
scheduler(`优先级`, `setState 对应的重渲染任务`)
  1. 在 useTransition 这个上下文里面 setState,他就会申请到一个 transition 车道,对应的是空闲事件优先级。那么 setState 安排的重渲染任务他是通过宏任务执行。并且他的优先级是最低,是最不重要的,会开启一个叫做 时间切片 的东西。

时间切片就是说,setState 安排的重渲染任务变成了可中断的每 5ms 停止执行,看下图

js 复制代码
function `setState 对应的重渲染任务`() {
  while (执行超过5ms了) {
    重渲染一个 `fiber`
    `performUnitOfWork`(); 
  }
  if (所有的 fiber 还没渲染完) {
    return `setState 对应的重渲染任务`
  }
}
  1. 你看上面的代码,超过 5ms 退出循环后干了什么?返回了这个函数他本身。

返回的这个函数本身 setState 对应的重渲染任务有什么用?

上面我已经把全部原理讲完了,我给一点提示,你们重新看一下文章对应的部分应该就懂了

  1. 记不记得上面提到过的, scheduler(优先级, setState 对应的重渲染任务)

  2. 记不记得上面提到过的,在 scheduler 内部,如果这个函数的返回值是一个函数,就退出本次的循环,这个任务保留,重新开始调度一个新的循环

🤖 相关

跟我一样看过源码的人,可能你可能会出现一个疑问?

当前 fiber 暂停渲染后,再次恢复执行,到底是从头开始重渲染,还是从当前的 fiber 开始重渲染。通过我长期的观察,我找到了真相。

又能水一篇文章🥰
面试官:你说你做过组件库,肯定了解过复杂组件状态管理的useSyncExternalStore吧?我:😭

面试官:你跟我说 setState 是同步的,它不是异步的吗?背错面试题了吧你!我:😭

面试官:你说你开发过组件库,那你怎么会不知道受控组件?面试就到这里吧。我:😭
版权归许泽川所有

如需转载,请提前询问本人的许可

相关推荐
康小汪8 小时前
AI 写 Vue 总写成同一个味道:给它装 Skills,装的不是知识是边界
前端·vue.js·人工智能·ai编程·最佳实践
智能运维指南9 小时前
研制过程“两张皮“怎么破:研制一体化支撑平台的定位、能力边界与落地前提
java·前端·人工智能·嘉为蓝鲸
白山编程大哥10 小时前
Java 后端如何优雅地把 List 集合返回给前端
java·前端·list
Flynt11 小时前
我把热榜那篇"禁用 axios"逐条实测了一遍:结论大体对,坑在它没讲的地方
前端·javascript·axios
考研保研资料分享11 小时前
四非会计保研中国矿大(北京):七场考核、候补与择校复盘
面试
Csvn12 小时前
bundle优化
前端
北冥有鱼12 小时前
发版后动态路由点击报 `Failed to fetch dynamically imported module`」问题上的完整排查与修复过程
前端·vue.js
静默回滚12 小时前
视频压到 25 MB 以内,码率要算、音轨要扣、余量要留
前端
用户372037492601812 小时前
把 10MB 中文语义模型塞进浏览器:STSB 做到教师模型的 93%,但线上 top1 只有 42%
前端
光锥智能13 小时前
海康机器人举行2026移动机器人新品发布会:箱式存拣升级,「明智」系列发布
java·前端·机器人