“This is the 21st day of my participation in the Gwen Challenge in November. See details: The Last Gwen Challenge in 2021”
React has functions such as cancelCallback, scheduleCallback, scheduleSyncCallback, and scheduleMicrotask. CancelCallback and scheduleCallback come from a library called Scheduler.
// packages/react-reconciler/src/Scheduler.js
import * as Scheduler from 'scheduler';
export const scheduleCallback = Scheduler.unstable_scheduleCallback;
export const cancelCallback = Scheduler.unstable_cancelCallback;
Copy the code
The scheduler is introduced
React, in short, uses it for collaborative scheduling in the browser environment. At first I thought it was a third party library, but it was found in the Packages/Scheduler directory of the React repository.
/ SRC /forks/Scheduler’; The steed goes to scheduler.js, about 600 lines of code, but instead of starting at the beginning, I’ll look at unstable_scheduleCallback and unstable_cancelCallback
unstable_scheduleCallback
Function signatures
function unstable_scheduleCallback(priorityLevel, callback, options) {}
Copy the code
Code logic
- Get the current time
currentTime
, plus the delay timeoptions.delay
, calculate the start timestartTime
- According to the
priorityLevel
You get different values of thetatimeout
- ExpirationTime expirationTime = startTime + timeout
- Create a new task
var newTask = {
id: taskIdCounter++,
callback,
priorityLevel,
startTime,
expirationTime,
sortIndex: -1,
};
Copy the code
- if
newTask
Is a delayed task, that is, the delay time is not 0, sostartTime
For sortIndex, put a name namedtimerQueue
Is in the priority queue. - if
taskQueue
The task is emptytimerQueue
Check the highest priority in theisHostTimeoutScheduled
Flag iftrue
The callcancelHostTimeout
Function, otherwise markedisHostTimeoutScheduled
To true. Check outisHostTimeoutScheduled
After that, schedule a timeout. (Essentially, if the new task has the highest priority, the original task is cancelled and the new task is given priority)
requestHostTimeout(handleTimeout, startTime - currentTime);
Copy the code
- if
newTask
If the task is not delayed, it is put into the task queue by sorting the index by expiration timetaskQueue
. - if
isHostCallbackScheduled
To false andisPerformingWork
False, flagisHostCallbackScheduled
If true, executerequestHostCallback(flushWork);
- Finally newTask is returned
What does requestHostTimeout and cancelHostTimeout do? What does the requestHostCallback do?
RequestHostTimeout is essentially a setTimeout timer macro task scheduling.
function requestHostTimeout(callback, ms) {
taskTimeoutID = localSetTimeout(() => {
callback(getCurrentTime());
}, ms);
}
Copy the code
In this case, localSetTimeout is the alias of the setTimeout function. The alias is used to prevent the user from overwriting the global setTimeout function.
Similarly, localClearTimeout is an alias for clearTimeout. CancelHostTimeout calls localClearTimeout and resets taskTimeoutID to -1.
As for requestHostCallback, it takes a callback argument assigned to the global variable scheduledHostCallback, Then open callbackschedulePerformWorkUntilDeadline – > performWorkUntilDeadline – > scheduledHostCallback – > schedulePerformWorkUntilDeadline news circulation until scheduledHostCallback call return values to false, will scheduledHostCallback reset to null.
FlushWork {flushWork} flushWork {requestHostCallback} flushWork {flushWork}
function flushWork(hasTimeRemaining, initialTime) { isHostCallbackScheduled = false; If (isHostTimeoutScheduled) {timeout isHostTimeoutScheduled = false; if (isHostTimeoutScheduled) {timeout isHostTimeoutScheduled = false; cancelHostTimeout(); } isPerformingWork = true; const previousPriorityLevel = currentPriorityLevel; try { return workLoop(hasTimeRemaining, initialTime); } finally { currentTask = null; currentPriorityLevel = previousPriorityLevel; isPerformingWork = false; }}Copy the code
unstable_cancelCallback
The simple thing is to empty the callback field of the input parameter
function unstable_cancelCallback(task) {
if (enableProfiling) {
// ...
}
// Null out the callback to indicate the task has been canceled. (Can't
// remove from the queue because you can't remove arbitrary nodes from an
// array based heap, only the first one.)
task.callback = null;
}
Copy the code
Next up
- What does workLoop in flushWork do?
- What is the overall principle of task scheduling in this library?