Javascript setTimeout 设置为 0 毫秒时在做什么?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/33955650/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-23 15:42:44  来源:igfitidea点击:

What is setTimeout doing when set to 0 milliseconds?

javascriptsettimeout

提问by DDan

In JavaScript, setTimeout(callback, delay)means "call callbackafter delaymilliseconds". But what if delayis 0? Should it call callbackright away?

在 JavaScript 中,setTimeout(callback, delay)表示“毫秒callback后调用delay”。但是如果delay0呢?它应该立即调用callback吗?

I am confused because of what I see when I run the following code:

我很困惑,因为我在运行以下代码时看到的内容:

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'); 
}

This logs the following to the console:

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

console_log

控制台日志

I expected to see AAAlogged much sooner than that. There was time to execute 4000 other calls to console.logbefore a function which should have been called immediately.

我预计AAA会比这更早地看到记录。有时间console.log在本应立即调用的函数之前执行 4000 次其他调用。

Can someone explain what setTimeoutis doing when the delay is set to 0 milliseconds?

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

回答by Jordan Gray

A few useful facts might help clarify what's happening:

一些有用的事实可能有助于澄清正在发生的事情:

  1. JavaScript is single-threaded. Asynchronous callbacks are assigned to a messageplaced in a message queue.
  2. When no code is currently executing, the event looppolls the message queue, requesting the next message in line to be processed (executed).
  3. setTimeoutadds a message (with the callback provided) to the end of this queue after the specified delay has elapsed.
  1. JavaScript 是单线程的。异步回调被分配到一个消息放置在消息队列中
  2. 当当前没有代码正在执行时,事件循环轮询消息队列,请求处理(执行)队列中的下一条消息。
  3. setTimeout在指定的延迟过后,将一条消息(提供回调)添加到此队列的末尾。

(Note: this means the delay in a setTimeoutcall is not a sure thing; it is the minimum delaybefore the callback is executed. The actual time taken depends on how long it takes to process any messages ahead of it in the queue.)

(注意:这意味着setTimeout调用中的延迟是不确定的;它是执行回调之前的最小延迟。实际花费的时间取决于处理队列中它前面的任何消息所需的时间。)

So what happens if the delay is set to 0? A new message is added to the queue immediately, and will be processed when the currently executing code is finished and any previously-added messages have been processed.

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

What's happening in your code

你的代码发生了什么

When you invoke setTimeout

当你调用setTimeout

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

…a message gets added to the queue with the specified callback. The rest of your code…

...一条消息被添加到具有指定回调的队列中。其余的代码……

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

…continues executing synchronously. Once it has completely finished, the event loop polls the message queue for the next message and finds the one with your setTimeoutcallback, which is then processed (the callback is run).

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

The callback only ever gets executed afterthe currently executing code has finished, no matter how long that takes.

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

Further reading

进一步阅读

For more details on the event loop, see:

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