在JavaScript中,setTimeout(callback, delay)
表示“callback
毫秒后调用delay
”。但是如果delay
是0
怎么办?它应该立即致电callback
吗?
我很困惑,因为我在运行以下代码时看到的内容:
setTimeout(function() {
console.log('AAA');
}, 0); // Call this in 0 milliseconds
for (i = 0; i < 1000; i++) {
console.log('BBB');
}
for (i = 0; i < 1000; i++) {
console.log('CCC');
}
for (i = 0; i < 1000; i++) {
console.log('DDD');
}
for (i = 0; i < 1000; i++) {
console.log('EEE');
}
这会将以下内容记录到控制台:
我希望看到AAA
的记录早得多。在应该立即调用的函数之前,有时间对console.log
执行4000次其他调用。
有人可以解释当延迟设置为0毫秒时setTimeout
正在做什么吗?
答案 0 :(得分:53)
一些有用的事实可能有助于澄清发生了什么:
setTimeout
在指定的延迟过去后,将一条消息(提供回调)添加到此队列的末尾。(注意:这意味着setTimeout
通话中的延迟并不确定;在执行回调之前,它是最小延迟。实际花费的时间取决于多长时间它需要在队列中处理它前面的任何消息。)
那么如果将延迟设置为0
会发生什么?一条新消息立即被添加到队列中,并将在当前正在执行的代码完成并且已处理任何先前添加的消息时进行处理。
当您调用setTimeout
...
setTimeout(function() {
console.log('AAA');
}, 0);
...使用指定的回调将消息添加到队列中。你的其余代码......
for (i = 0; i < 1000; i++) {
console.log('BBB');
}
// etc.
...继续同步执行。完成后,事件循环会轮询消息队列以查找下一条消息,并找到一条带有setTimeout
回调的消息,然后进行处理(运行回调)。
只有在当前正在执行的代码完成后,回调才会被执行,无论需要多长时间。
有关事件循环的更多详细信息,请参阅: