如果代码较大并且调用堆栈不为空,那么事件循环如何在2秒内准确执行代码



很多解释都说调用堆栈是空的,但我不明白,如果我们设置一个2秒的定时器并以异步方式执行代码,如果我有一个运行时间为10秒的代码,而调用堆栈不是空的,回调队列中的回调函数会等待11秒执行吗?

是。想象一下这个代码:

setTimeout(function() {
console.log('hi');
}, 0);
let i = 0;
while (i <= 1e9) {
i++;
}

这里发生了什么?

CCD_ 1内部的代码是";"延期";在0ms之后运行";在当前调用堆栈为空之后";。

但当前脚本必须完成循环。因此,如果您运行此代码,它将等待i计数为1e9,然后再记录"0";嗨"到控制台。

jsfiddle码

。。。回调队列中的回调函数会等待11秒执行吗?

不一定是11秒,否;它将在10秒同步代码完成后不久运行。计时器的长度是否短于同步代码的持续时间并不重要。有关Node.js事件循环如何工作的更多详细信息,请参阅本页。

例如,使用此代码:

function elapsed(start) {
const elapsed = Date.now() - start;
return `${(elapsed / 1000).toFixed(4)}s`;
}
const startTimer = Date.now();
console.log(`Starting timer`);
setTimeout(() => {
console.log(`Timer fired after ${elapsed(startTimer)}`);
}, 2000);
const finish = Date.now() + 10000;
const startBusyWait = Date.now();
console.log(`Starting to wait`);
while (Date.now() < finish) {
// Busy-wait -- DON'T DO THIS
}
console.log(`Done busy-waiting after ${elapsed(startBusyWait)}`);

你会看到这样的东西:

启动计时器开始等待10点后忙着等待计时器在10.0050s
之后启动

最新更新