设置为0毫秒时setTimeout的作用是什么?

时间:2015-11-27 10:44:40

标签: javascript settimeout

在JavaScript中,setTimeout(callback, delay)表示“callback毫秒后调用delay”。但是如果delay0怎么办?它应该立即致电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'); 
}

这会将以下内容记录到控制台:

console_log

我希望看到AAA的记录早得多。在应该立即调用的函数之前,有时间对console.log执行4000次其他调用。

有人可以解释当延迟设置为0毫秒时setTimeout正在做什么吗?

1 个答案:

答案 0 :(得分:53)

一些有用的事实可能有助于澄清发生了什么:

  1. JavaScript是单线程的。异步回调分配给放置在消息队列中的消息
  2. 当没有代码正在执行时,事件循环轮询消息队列,请求处理(执行)行中的下一条消息。
  3. setTimeout在指定的延迟过去后,将一条消息(提供回调)添加到此队列的末尾。
  4. (注意:这意味着setTimeout通话中的延迟并不确定;在执行回调之前,它是最小延迟。实际花费的时间取决于多长时间它需要在队列中处理它前面的任何消息。)

    那么如果将延迟设置为0会发生什么?一条新消息立即被添加到队列中,并将在当前正在执行的代码完成并且已处理任何先前添加的消息时进行处理。

    您的代码中发生了什么

    当您调用setTimeout ...

    setTimeout(function() { 
        console.log('AAA');
    }, 0);
    

    ...使用指定的回调将消息添加到队列中。你的其余代码......

    for (i = 0; i < 1000; i++) {
        console.log('BBB'); 
    }
    // etc.
    

    ...继续同步执行。完成后,事件循环会轮询消息队列以查找下一条消息,并找到一条带有setTimeout回调的消息,然后进行处理(运行回调)。

    只有在当前正在执行的代码完成后,回调才会被执行,无论需要多长时间。

    进一步阅读

    有关事件循环的更多详细信息,请参阅: