我正在阅读一系列在线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。
任何人都可以澄清一下幕后发生的事情,以及我应该知道的有关延误的任何问题吗?
答案 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毫秒,因此首先执行。