【问题标题】:Why is the setTimeout with 0 seconds last to finish [duplicate]为什么 setTimeout 的最后完成时间为 0 秒[重复]
【发布时间】:2019-04-23 15:05:53
【问题描述】:

所以我想出了这个例子,我不明白为什么 0 秒的 setTimeout 是最后一个被执行的

function waitThreeSeconds() {
  setTimeout(function() {
    console.log("Finished Function");
  }, 0);
}

function clickHandler() {
  console.log("Clicked");
}

document.addEventListener('click', clickHandler);

waitThreeSeconds();

//waiting 5 seconds 
var ms = 5000 + new Date().getTime();
while (new Date() < ms) {}


console.log('Finished Execution');

如果确实将 setTimeouts 回调添加到队列中,为什么每次我执行单击事件时,它都会更早地添加到队列中,然后是 setTimeout 的回调。直到全局执行上下文('main')从堆栈中弹出

【问题讨论】:

  • 是的,我添加了 5 秒的 while 循环,以便在有意义的情况下可以在队列中累积。所有的回调都将在队列中等待。我的问题是为什么 setTimeout 的回调最后发生
  • while (new Date() &lt; ms) {} 是一个繁忙的循环,而它正在运行,没有其他东西可以运行
  • 也许也来自同一个资源:当前执行的代码必须在队列上的函数执行之前完成,因此生成的执行顺序可能与预期不同。
  • 我不了解 JavaScript,但在许多窗口模型中,用户输入是高优先级的事件,而计时器事件的优先级非常低,往往仅在处理完所有其他未决事件后才提供服务。

标签: javascript asynchronous synchronous


【解决方案1】:

由于事件循环,javascript的每个事件都归于一个 执行进程所遵循的堆栈,注册 settimeout 0 , 在 que 中制作,当事件循环将执行时它将执行 在等待中完成剩下的其他任务。

对于参考请看这个惊人的解释:Philip roberts

https://www.youtube.com/watch?v=8aGhZQkoFbQ&vl=en

【讨论】:

    【解决方案2】:

    是的,@KenY-N 在问题评论中所说的确实如此。

    我之前就承诺回调 (https://stackoverflow.com/a/40882544/5217142) 回答过这个问题:

    在 HTML 术语中,来自同一域的一个页面或一组页面的 event loop 可以有多个 task queues。来自同一个task source 的任务总是进入同一个队列,由浏览器选择接下来要使用的任务队列。

    运行定时器回调的任务来自timer task source并进入同一个队列......

    这里的区别是你问的是点击事件的任务队列优先级是否高于定时器回调。

    通过检查,您的代码显示答案是肯定的:在您尝试过的浏览器中,点击事件的任务队列优先于计时器回调的任务队列。

    【讨论】:

      猜你喜欢
      • 2017-04-24
      • 2016-03-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-03-22
      • 1970-01-01
      • 1970-01-01
      • 2014-10-15
      相关资源
      最近更新 更多