【问题标题】:Why setTimeout code blocked?为什么 setTimeout 代码被阻塞?
【发布时间】:2017-01-26 01:32:32
【问题描述】:
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.

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

【问题讨论】:

  • JavaScript 不是“多线程的”;函数串行执行,而不是并行执行。

标签: javascript asynchronous settimeout


【解决方案1】:

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

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

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

注意:回调队列将在调用堆栈中没有要执行的内容时开始执行。

最好的阅读,Event Loop

【讨论】:

  • 那么while(){}中的代码不会同时被执行?
  • @lx1412 是的,callBack 队列中的函数将作为正常数组中函数的正常执行来执行。一个接一个。
【解决方案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);

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-12-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-08-11
    • 1970-01-01
    相关资源
    最近更新 更多