Jake Archibald talk about event loop
了解到浏览器中有3个队列:
在执行项目时表现不同。
回调队列一次执行一个回调,这意味着在执行回调之后,浏览器会在继续下一个回调之前检查是否还有其他事情要做(比如重新呈现页面)。
动画队列用于
requestAnimationFrame
回调,它还执行它的项,直到队列中除了添加到当前执行的回调中的回调(这些回调在下一帧执行)之外,其余的都是空的。
我想检查一下,并创建了一个递归调用的脚本
请求动画帧
排队等待50次超时回调,阻塞主线程15毫秒。
for (let i = 0; i < 50; i++) {
setTimeout(() => {
block(15);
console.log(`timeout ${i}`)
})
}
const startDate = Date.now();
function raf() {
requestAnimationFrame((x) => {
if (Date.now() < startDate + 1000) {
console.log(`raf ${x}`)
raf();
}
})
}
raf();
function block(ms) {
const startDate = Date.now();
while (Date.now() < startDate + ms) { }
}
现场演示:
https://stackblitz.com/edit/js-xdpbbb?file=index.js
因为块时间大致等于帧之间的时间(60fps给出16.666ms),所以我希望raf和超时回调之间会出现交织模式。但结果却完全不同:
如您所见,在raf回调之间大约有10个超时回调,需要大约150毫秒才能完成。为什么不是这样:
-
-
动画cb
-
超时cb
-
?