简介
Scheduler主要用于调度执行Reconciler
组成
api
- unstable_scheduleCallback
- unstable_cancelCallback
调度回调有两种方式
- setTimeout
- 通过MessageChannel
Task
为任务调度单元
type Task = {
id: number,
callback: Callback | null,
priorityLevel: PriorityLevel,
startTime: number,
expirationTime: number,
sortIndex: number,
isQueued?: boolean,
};
双堆
维护两个最小堆,按Task的sortIndex排序
taskQueue:排序键为expirationTime,startTime小于等于当前时间currentTime的任务放入此堆中timerQueue:排序键为startTime,startTime大于当前时间currentTime的任务放入此堆中
var taskQueue: Array<Task> = [];
var timerQueue: Array<Task> = [];
优先级 到超时时间 的映射
| 优先级 | timeout超时时间 |
|---|---|
ImmediatePriority | -1立即超时 |
UserBlockingPriority | const userBlockingPriorityTimeout = 250 |
IdlePriority | maxSigned31BitInt = 1073741823永远不会超时 |
LowPriority | const lowPriorityTimeout = 10000 |
NormalPriority | const normalPriorityTimeout = 5000 |
调度工作循环workLoop
function workLoop(initialTime: number) {
let currentTime = initialTime;
advanceTimers(currentTime);
currentTask = peek(taskQueue);
while (currentTask !== null) {
if (!enableAlwaysYieldScheduler) {
if (currentTask.expirationTime > currentTime && shouldYieldToHost()) {
// This currentTask hasn't expired, and we've reached the deadline.
break;
}
}
// $FlowFixMe[incompatible-use] found when upgrading Flow
const callback = currentTask.callback;
if (typeof callback === 'function') {
// $FlowFixMe[incompatible-use] found when upgrading Flow
currentTask.callback = null;
// $FlowFixMe[incompatible-use] found when upgrading Flow
currentPriorityLevel = currentTask.priorityLevel;
// $FlowFixMe[incompatible-use] found when upgrading Flow
const didUserCallbackTimeout = currentTask.expirationTime <= currentTime;
if (enableProfiling) {
// $FlowFixMe[incompatible-call] found when upgrading Flow
markTaskRun(currentTask, currentTime);
}
const continuationCallback = callback(didUserCallbackTimeout);
currentTime = getCurrentTime();
if (typeof continuationCallback === 'function') {
// If a continuation is returned, immediately yield to the main thread
// regardless of how much time is left in the current time slice.
// $FlowFixMe[incompatible-use] found when upgrading Flow
currentTask.callback = continuationCallback;
if (enableProfiling) {
// $FlowFixMe[incompatible-call] found when upgrading Flow
markTaskYield(currentTask, currentTime);
}
advanceTimers(currentTime);
return true;
} else {
if (enableProfiling) {
// $FlowFixMe[incompatible-call] found when upgrading Flow
markTaskCompleted(currentTask, currentTime);
// $FlowFixMe[incompatible-use] found when upgrading Flow
currentTask.isQueued = false;
}
if (currentTask === peek(taskQueue)) {
pop(taskQueue);
}
advanceTimers(currentTime);
}
} else {
pop(taskQueue);
}
currentTask = peek(taskQueue);
if (enableAlwaysYieldScheduler) {
if (currentTask === null || currentTask.expirationTime > currentTime) {
// This currentTask hasn't expired we yield to the browser task.
break;
}
}
}
// Return whether there's additional work
if (currentTask !== null) {
return true;
} else {
const firstTimer = peek(timerQueue);
if (firstTimer !== null) {
requestHostTimeout(handleTimeout, firstTimer.startTime - currentTime);
}
return false;
}
}

1093

被折叠的 条评论
为什么被折叠?



