为什么setTimeout代码被阻止?

时间:2016-09-18 06:40:49

标签: javascript asynchronous settimeout

function test(){
  setTimeout(function(){
    var now=new Date();
    while((new Date()).getTime() < now.getTime()+5000){ }
    console.log('p')
  }, 0);
}

test();
test(); //it takes 10 seconds,the second test function runs after the first finished.

有人可以向我解释它是如何运作的吗?

2 个答案:

答案 0 :(得分:5)

这种情况正在发生,因为每当你在function内传递setTimeout并调用它时,传递的函数将根据提供的延迟(毫秒)推送到callBack队列。 callBack队列中的函数将按照它们推送的顺序逐个执行。因此,在您的情况下,您通过运行function循环来阻止callBack队列中存在的while的代码流。因此,test的第二次调用需要10秒才能执行。

test(); //call 1
callBack queue ---->  [function(){ while(){} }]

test(); //call 2
callBack queue ---->  [function(){ while(){} }, function(){ while(){} }]

注意:当调用堆栈中没有任何内容要执行时,回调队列将开始执行。

最好阅读,Event Loop

答案 1 :(得分:2)

如果你想要一个非阻塞实现,你必须用异步递归替换你的同步while循环:

function test(x){
  setTimeout(function loop(now) {
    (new Date()).getTime() < now.getTime()+2000
     ? setTimeout(loop, 0, now)
     : console.log('p', x);
  },0, new Date())
}

test(1);
test(2);