这篇应该属于Scheduler任务调度一章中,但是由于篇幅原因,单独拧出来
思路
我们已经知道,React源码是利用MessageChannel/setImmediate生成宏任务,在浏览器刷新的每一帧中见缝插针的执行React任务。
因为是参考requestIdleCallback实现的一帧内剩余时间能执行就执行,不能执行就暂停的原则。所以需要考虑实现下面几件事:
- 1.如何确定一帧有多久
- 2.当前帧对应的deadline
- 3.判断是否需要让出执行权
一帧有多久(yieldInterval)
是通过变量yieldInterval确定。是定时器每次执行的时间间隔,也是浏览器一帧对应的时间。通过浏览器的fps来确定
- 定义常量
let yieldInterval = 5;
- 根据浏览器fps确定(forceFrameRate函数)
/**
@params fps:当前浏览器每秒多少帧
*/
function forceFrameRate(fps) {
if (fps > 0) {
yieldInterval = Math.floor(1000 / fps);
} else {
yieldInterval = 5;
}
}
当前帧什么时候结束(deadline)
确定了一帧时间长度以后,就需要确定在当前帧,什么时候结束,也就是结束的时候,要主动让出js执行权,交出cpu,防止阻塞
- 定义常量
let deadline = 0;
- 更新截止时间(performWorkUntilDeadline函数)
const performWorkUntilDeadline = () => {
const currentTime = getCurrentTime();
deadline = currentTime + yieldInterval;
};
当然performWorkUntilDeadline函数绝不止更新了deadline这一个功能,还会去主动执行当前任务(scheduleHostCallback常量/函数)
判断到时间了
既然截止时间也有了,只需要判断当前时间是否到截止时间了就好(shouldYieldToHost函数)
function shouldYieldToHost() {
getCurrentTime() >= deadline
}
传送门
【欢迎探讨】