react源码学习之Scheduler

简介

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,};

双堆

维护两个最小堆,按TasksortIndex排序

  • taskQueue:排序键为expirationTimestartTime小于等于当前时间currentTime的任务放入此堆中
  • timerQueue:排序键为startTimestartTime大于当前时间currentTime的任务放入此堆中
vartaskQueue:Array<Task>=[];vartimerQueue:Array<Task>=[];

优先级 到超时时间 的映射

优先级timeout超时时间
ImmediatePriority-1立即超时
UserBlockingPriorityconst userBlockingPriorityTimeout = 250
IdlePrioritymaxSigned31BitInt = 1073741823永远不会超时
LowPriorityconst lowPriorityTimeout = 10000
NormalPriorityconst normalPriorityTimeout = 5000

调度工作循环workLoop

functionworkLoop(initialTime:number){letcurrentTime=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 Flowconstcallback=currentTask.callback;if(typeofcallback==='function'){// $FlowFixMe[incompatible-use] found when upgrading FlowcurrentTask.callback=null;// $FlowFixMe[incompatible-use] found when upgrading FlowcurrentPriorityLevel=currentTask.priorityLevel;// $FlowFixMe[incompatible-use] found when upgrading FlowconstdidUserCallbackTimeout=currentTask.expirationTime<=currentTime;if(enableProfiling){// $FlowFixMe[incompatible-call] found when upgrading FlowmarkTaskRun(currentTask,currentTime);}constcontinuationCallback=callback(didUserCallbackTimeout);currentTime=getCurrentTime();if(typeofcontinuationCallback==='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 FlowcurrentTask.callback=continuationCallback;if(enableProfiling){// $FlowFixMe[incompatible-call] found when upgrading FlowmarkTaskYield(currentTask,currentTime);}advanceTimers(currentTime);returntrue;}else{if(enableProfiling){// $FlowFixMe[incompatible-call] found when upgrading FlowmarkTaskCompleted(currentTask,currentTime);// $FlowFixMe[incompatible-use] found when upgrading FlowcurrentTask.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 workif(currentTask!==null){returntrue;}else{constfirstTimer=peek(timerQueue);if(firstTimer!==null){requestHostTimeout(handleTimeout,firstTimer.startTime-currentTime);}returnfalse;}}

AI数字营销平台