300 行代码实现 React 的调度器 Scheduler

本文通过300行代码简化了React的Scheduler模块,保留关键功能并添加详细注释,便于学习源码。提供了Schedule.js和ScheduleMinHeap.js的源码及测试代码,适合前端开发者了解和研究React的调度机制。
摘要由CSDN通过智能技术生成

前言

说是实现,但其实我们只是在 React Scheduler 源码的基础上进行了简化,省略掉一些繁琐的细节,添加了丰富的注释,保证代码可直接执行。

大家可以复制代码到编辑器中,直接运行,非常适合学习 React 源码用。

如果看注释还不了解,欢迎补充学习这个专栏的文章。

源码 Schedule.js

// 引入最小堆封装代码
import {push, pop, peek} from './ScheduleMinHeap.js';

// 浏览器提供的 API,获取从 time origin(当前文档生命周期的开始节点时间) 之后到当前调用时经过的时间,它以一个恒定的速率慢慢增加的,不会受到系统时间的影响,具体参考:https://juejin.cn/post/7171633315336683528
let getCurrentTime = () => performance.now();

// Scheduler 优先级划分,数字越小优先级越高,0 表示没有优先级
const NoPriority = 0;
const ImmediatePriority = 1;
const UserBlockingPriority = 2;
const NormalPriority = 3;
const LowPriority = 4;
const IdlePriority = 5;

// Scheduler 根据优先级设置的对应 timeout 时间,越小越紧急
// 在 React 中,任务是可以被打断的,但是任务不能一直被打断,所以要设置一个超时时间,过了这个时间就必须立刻执行
// timeout 就表示超时时间
var IMMEDIATE_PRIORITY_TIMEOUT = -1;
var USER_BLOCKING_PRIORITY_TIMEOUT = 250;
var NORMAL_PRIORITY_TIMEOUT = 5000;
var LOW_PRIORITY_TIMEOUT = 10000;
// 为什么是 1073741823,查看:https://juejin.cn/post/7171633315336683528
var IDLE_PRIORITY_TIMEOUT = 1073741823;

// 普通任务队列,它是一个最小堆结构,最小堆查看:https://juejin.cn/post/7168283003037155359
var taskQueue = [];
// 延时任务队列,它同样是一个最小堆结构
var timerQueue = [];
// taskId
var taskIdCounter = 1;

// 任务队列是否正在被遍历执行,workLoop 执行前为 true,执行完成后改为 false
var isPerformingWork = false;
// 是否有正在执行的 requestHostCallback,它会在 requestHostCallback 调用前设为 true,workLoop 执行前改为 false
var isHostCallbackScheduled = false;
// 是否有正在执行的 requestHostTimeout,它会在 requestHostTimeout 执行前设为 true,cancenlHostTimeout 和 handleTimeout 中设为 false
var isHostTimeoutScheduled = false;
// message loop 是否正在执行,它会在 schedulePerformWorkUntilDeadline 前设为 true,在任务队列执行完毕后设为 false
let isMessageLoopRunning = false;

// 记录 requestHostCallback 执行时传入的 callback 函数,也就是 flushWork
let scheduledHostCallback = null;
// 用于 cancelHostTimeout 取消 requestHostTimeout
let taskTimeoutID = -1;

// 记录当前正在执行的任务
var currentTask = null;
var currentPriorityLevel = NormalPriority;

// 这里是调度的开始
function unstable_scheduleCallback(priorityLevel, callback, options) {var currentTime = getCurrentTime();// 任务被安排调度的时间,相当于去银行时的点击排号机器的那个时间var startTime;if (typeof options === 'object' && options !== null) {var delay =
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值