调度器
文章目录
- 调度器
-
- import内容
- 变量
- 方法
-
- *advanceTimers*(currentTime)
- *flushWork*(hasTimeRemaining, initialTime)
- *workLoop*(hasTimeRemaining, initialTime)
- *requestHostTimeout*(callback, ms)
- *handleTimeout*(currentTime)
- *unstable_runWithPriority*(priorityLevel, eventHandler)
- *unstable_next*(eventHandler)
- *unstable_wrapCallback*(callback)
- *unstable_scheduleCallback*(priorityLevel, callback, options)
- *unstable_pauseExecution*()、*unstable_continueExecution*()
- *unstable_getFirstCallbackNode*()
- *unstable_cancelCallback*(task)
- *shouldYieldToHost*()
- *requestPaint*()
- *forceFrameRate*(fps)
- *performWorkUntilDeadline*
- 总结
react scheduleru作为一个单独的包发布,就叫做
scheduler
本文来看一看调度器的代码
位置:...\packages\scheduler\src\forks\Scheduler.js
import内容
import {
// 调度debug flag
enableSchedulerDebugging,
// 调度性能测试 flag
enableProfiling,
} from '../SchedulerFeatureFlags';
// 导入堆的push、pop、peek(若堆长度不为0,获取第一个元素)方法
import {
push, pop, peek} from '../SchedulerMinHeap';
// 五种调度优先度
import {
ImmediatePriority,
UserBlockingPriority,
NormalPriority,
LowPriority,
IdlePriority,
} from '../SchedulerPriorities';
// 用于性能优化的一些行为标记方法
import {
markTaskRun,
markTaskYield,
markTaskCompleted,
markTaskCanceled,
markTaskErrored,
markSchedulerSuspended,
markSchedulerUnsuspended,
markTaskStart,
stopLoggingProfilingEvents,
startLoggingProfilingEvents,
} from '../SchedulerProfiling';
// 用户输入导致挂起行为flag
import {
enableIsInputPending} from '../SchedulerFeatureFlags';
变量
// 调度器的当前时间
let getCurrentTime;
// 用于性能分析
// performance.now()方法返回一个精确到毫秒的DOMHighResTimeStamp
const hasPerformanceNow =
typeof performance === 'object' && typeof performance.now === 'function';
// 如果有performance可供使用,则用performance的方法记录当前时间,如果没有,则用Date记录当前时间。
if (hasPerformanceNow) {
const localPerformance = performance;
getCurrentTime = () => localPerformance.now();
} else {
const localDate = Date;
const initialTime = localDate.now();
getCurrentTime = () => localDate.now() - initialTime;
}
// V8引擎下的最大的Int值
var maxSigned31BitInt = 1073741823;
// 定义不同场景下的定时值
// 即刻执行
var IMMEDIATE_PRIORITY_TIMEOUT = -1;
// 经过特定时间执行
var USER_BLOCKING_PRIORITY_TIMEOUT = 250;
var NORMAL_PRIORITY_TIMEOUT = 5000;
var LOW_PRIORITY_TIMEOUT = 10000;
// 永不执行
var IDLE_PRIORITY_TIMEOUT = maxSigned31BitInt;
// 任务和计时器的队列,各自储存在堆上
var taskQueue = [];
var timerQueue = [];
// 递增的id计数器,用于维护插入顺序
var taskIdCounter = 1;
// 用于debug的暂定调度器flag
var isSchedulerPaused = false;
// 当前任务
var currentTask = null;
// 当前优先度
var currentPriorityLevel = NormalPriority;
// 在进行工作时此flag置为真,以免多次重入工作
var isPerformingWork = false;
// host回调、过期调度flag
var isHostCallbackScheduled = false;
var isHostTimeoutScheduled = false;
// 获取本地对原生API的引用,以免被兜底代码包覆盖
const localSetTimeout = typeof setTimeout === 'function' ? setTimeout : null;
const localClearTimeout =
typeof clearTimeout === 'function' ? clearTimeout : null;
const localSetImmediate =
typeof setImmediate !== 'undefined' ? setImmediate : null; // IE and Node.js + jsdom
方法
advanceTimers(currentTime)
function advanceTimers(currentTime) {
// 检查不再延迟的任务,将它们入队
let timer = peek(timerQueue);
while (timer !== null) {
// 如果取得的timer没有回调函数,则将timer弹出
if (timer.callback === null) {
pop(timerQueue);
} else if (timer.startTime <= currentTime) {
// 如果timer设置的开始时间已经到了,则将timer划分到任务队列中
pop(timerQueue);
// 根据timer的截止时间设置排序索引
timer.sortIndex = timer.expirationTime;
// 将timer推送到任务队列中
push(taskQueue, timer);
if (enableProfiling) {
// 如果开启了性能分析,将行为记录
markTaskStart(timer, currentTime);
timer.isQueued = true;
}
} else {
// 其余情况timer仍在等待队列中
return;
}
// 处理下一个timer,直到检查完队列中所有timer
timer = peek(timerQueue)