了解SetTimeout顺序

时间:2015-10-13 16:58:07

标签: javascript

我正在阅读一系列在线javascript面试问题并注意到以下问题:

function printing() {
  console.log(1); 
  setTimeout(function() { console.log(2); }, 1); 
  setTimeout(function() { console.log(3); }, 2); 
  setTimeout(function() { console.log(4); }, 0); 
  console.log(5);
}
printing();

我希望以下代码将以下代码打印到控制台:1,5,4,3,2 我的理由是首先执行console.log(1)和console.log(2),同时将setTimeout发送到eventloop,等待一切先完成。一旦打印出5,JS将查看队列,然后4,3,2将推送/弹出。

但是,在我的Chrome浏览器上,我注意到了1,5,2,4,3。

我很困惑,但同时有一种预感,可能是由于超时延迟的小幅增加导致打嗝(可能是浏览器的事情?)。我的原因是因为我在每个数字后面加了两个零,这样延迟就变成100,200和0。

任何人都可以澄清一下幕后发生的事情,以及我应该知道的有关延误的任何问题吗?

2 个答案:

答案 0 :(得分:2)

在这里,我将举例说明执行的执行情况:

  console.log(1);                                   // Run log "1"
  setTimeout(function() { console.log(2); }, 1);    // Add to queue timer1
  setTimeout(function() { console.log(3); }, 2);    // Add to queue timer2 
  setTimeout(function() { console.log(4); }, 0);    // Add to queue timer3
  console.log(5);                                   // Run log "5"
  // In queue [timer1, timer2, timer3]

  // [tick timer 1 => 0 time left => execute] log "2"
  // [tick timer 2 => 1 time left]
  // [timer 3 => 0 time left => execute] log "4"
  // [tick timer 2 => 0 time left => execute] log "3"

功能setTimeout(... , 0)setTimeout(..., 1)的工作方式相同。当我们勾选"超时队列" 中的每个计时器时,我们还会检查是否还有剩余时间。因此setTimeout(..., 1)会勾选并执行,而setTimeout(... , 0)只会执行。

答案 1 :(得分:0)

您必须了解调用堆栈。所有函数调用都放在调用堆栈上,如果堆栈为空则调用该函数。如果堆栈有条目,则在完成堆栈上的当前调用之前,不会调用该函数。

超时时,超时会调用调用堆栈。他们异步地这样做。因此,在当前执行期间可以在调用堆栈上进行调用。

超时没有优先级,首先在堆栈上执行。 1毫秒的超时超过调用堆栈的0毫秒,因此首先执行。