如果代码较大且调用堆栈不为空,事件循环如何在 2 秒内准确执行代码?
how event loop exactly executes code in 2 seconds if the code is larger and call stack is not empty?
很多解释都说调用栈是空的,但我不明白,如果我们设置一个 2 秒的计时器并以异步方式执行代码,如果我有一个代码 运行 10秒的时间,call-stack不为空,回调队列中的回调函数会等待11秒执行吗?
...will the callback function in the callback queue waits for 11 sec to be executed?
不一定是11秒,不是; 10 秒同步代码完成后不久,它将 运行。定时器的长度是否比同步代码持续时间短无关紧要。 this page 中有关 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)}`);
您会看到如下内容:
Starting timer
Starting to wait
Done busy-waiting after 10.0000s
Timer fired after 10.0050s
是的。想象一下这段代码:
setTimeout(function() {
console.log('hi');
}, 0);
let i = 0;
while (i <= 1e9) {
i++;
}
这里发生了什么?
setTimeout
中的代码被“推迟”到“当前调用堆栈为空后”0 毫秒后 运行。
但是当前脚本必须完成它的循环。因此,如果您 运行 这段代码,它将等到 i
计数到 1e9,然后再将“hi”记录到控制台。
很多解释都说调用栈是空的,但我不明白,如果我们设置一个 2 秒的计时器并以异步方式执行代码,如果我有一个代码 运行 10秒的时间,call-stack不为空,回调队列中的回调函数会等待11秒执行吗?
...will the callback function in the callback queue waits for 11 sec to be executed?
不一定是11秒,不是; 10 秒同步代码完成后不久,它将 运行。定时器的长度是否比同步代码持续时间短无关紧要。 this page 中有关 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)}`);
您会看到如下内容:
Starting timer Starting to wait Done busy-waiting after 10.0000s Timer fired after 10.0050s
是的。想象一下这段代码:
setTimeout(function() {
console.log('hi');
}, 0);
let i = 0;
while (i <= 1e9) {
i++;
}
这里发生了什么?
setTimeout
中的代码被“推迟”到“当前调用堆栈为空后”0 毫秒后 运行。
但是当前脚本必须完成它的循环。因此,如果您 运行 这段代码,它将等到 i
计数到 1e9,然后再将“hi”记录到控制台。