2023-03-13 10:40:08 +08:00

93 lines
2.6 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Scheduler调度延时任务
## *unstable_scheduleCallback*
```js
function unstable_scheduleCallback(priorityLevel,callback,options){
//...
if (startTime > currentTime) {
// 调度一个延时任务
requestHostTimeout(handleTimeout, startTime - currentTime);
} else {
// 调度一个普通任务
requestHostCallback(flushWork);
}
}
```
- 可以看到,调度一个延时任务的时候,主要是执行 requestHostTimeout
## requestHostTimeout
```js
// 实际上在浏览器环境就是 setTimeout
const localSetTimeout = typeof setTimeout === 'function' ? setTimeout : null;
/**
*
* @param {*} callback 就是传入的 handleTimeout
* @param {*} ms 延时的时间
*/
function requestHostTimeout(callback, ms) {
taskTimeoutID = localSetTimeout(() => {
callback(getCurrentTime());
}, ms);
/**
* 因此,上面的代码,就可以看作是
* id = setTimeout(function(){
* handleTimeout(getCurrentTime())
* }, ms)
*/
}
```
可以看到requestHostTimeout 实际上就是调用 setTimoutout然后在 setTimeout 中,调用传入的 handleTimeout
## handleTimeout
```js
/**
*
* @param {*} currentTime 当前时间
*/
function handleTimeout(currentTime) {
isHostTimeoutScheduled = false;
// 遍历timerQueue将时间已经到了的延时任务放入到 taskQueue
advanceTimers(currentTime);
if (!isHostCallbackScheduled) {
if (peek(taskQueue) !== null) {
// 从普通任务队列中拿一个任务出来
isHostCallbackScheduled = true;
// 采用调度普通任务的方式进行调度
requestHostCallback(flushWork);
} else {
// taskQueue任务队列里面是空的
// 再从 timerQueue 队列取一个任务出来
// peek 是小顶堆中提供的方法
const firstTimer = peek(timerQueue);
if (firstTimer !== null) {
// 取出来了,接下来取出的延时任务仍然使用 requestHostTimeout 进行调度
requestHostTimeout(handleTimeout, firstTimer.startTime - currentTime);
}
}
}
}
```
- handleTimeout 里面主要就是调用 advanceTimers 方法,该方法的作用是将时间已经到了的延时任务放入到 taskQueue那么现在 taskQueue 里面就有要执行的任务,然后使用 requestHostCallback 进行调度。如果 taskQueue 里面没有任务了,再次从 timerQueue 里面去获取延时任务,然后通过 requestHostTimeout 进行调度。
## 流程图
Scheduler 这一块儿大致的流程图如下:
<img src="https://xiejie-typora.oss-cn-chengdu.aliyuncs.com/2022-12-30-023505.png" alt="image-20221230103504711" style="zoom: 50%;" />