【问题标题】:How is execution queue generated in JavaScript?JavaScript 中的执行队列是如何产生的?
【发布时间】:2015-12-08 13:45:52
【问题描述】:

考虑这个简单的例子:

console.log('Start');

setTimeout(function() {
  console.log('First timeout');
}, 100);

setTimeout(function () {
  console.log('Second timeout');
}, 2000);

var time = Date.now();
for (var i = 0; i < 2000000000; i++) {
  var temp = i * i * Math.sqrt(i);
  temp = temp + temp;
}
console.log(Date.now() - time);

setTimeout(function () {
  console.log('Third timeout');
}, 50);

console.log('End');

输出是:

Start
1219
End
First timeout
Third timeout
Second timeout

是什么让我想到执行队列(堆栈?)的生成方式。我是对的,JavaScript解释器首先检查代码,生成队列,然后开始执行,当超时时间过去时,将超时函数添加到队列末尾(所以我们有预生成的执行队列,它在执行期间更新并动态生成超时列表)?

【问题讨论】:

  • 这个问题的确切原因是什么?您是否希望在日志中看到不同的顺序?
  • 您所询问的大部分内容都取决于实现——每个 JavaScript 引擎都可能以自己的方式做事。 JavaScript 规范(和 HTML 规范,这是定义 setTimeout 的地方)列出了应该采取的步骤/操作,但引擎可以以它选择的任何方式进行。
  • @Spikee 我试图让自己清楚地了解这个概念,以便将来理解它并能够在例如工作面试时解释它。
  • @JamesThorpe 是否有任何生产引擎可以不同地处理这个问题?
  • 不知道——我的兴趣只停留在规范上——它定义了事物在我感兴趣的级别上的行为方式。同样,我也没有看到 CLR 或 Mono 如何实现 CLI ...

标签: javascript asynchronous settimeout


【解决方案1】:

JavaScript 是单线程的。 超时调用被推送到事件循环,因此它们在所有主要流程调用之后执行。

console.log('Start');  **-> Printed #1 **

setTimeout(function() {
  console.log('First timeout');    **-> Pushed to eventloop #1 **
}, 100);

setTimeout(function () {
  console.log('Second timeout');**-> Pushed to eventloop  #3 !! **
}, 2000);

var time = Date.now();
for (var i = 0; i < 2000000000; i++) {
  var temp = i * i * Math.sqrt(i);
  temp = temp + temp;
}
console.log(Date.now() - time); **-> Printed #2 **

setTimeout(function () {
  console.log('Third timeout');  **-> Pushed to eventloop #2 !!**
}, 50);

console.log('End'); **-> Printed #3 **

注意:“第三次超时”被推送到事件循环 #2 而不是 #1,即使它有 50 毫秒与 100 毫秒(第一个),因为它是在你冗长的 for 循环之后处理的,这需要足够的时间来处理第一个超时。

EventLoop 解释:https://developer.mozilla.org/en-US/docs/Web/JavaScript/EventLoop

【讨论】:

  • 谢谢!看起来我走在正确的道路上。对于每个事件,js 将其添加到“事件循环”并调用相应的代码。所以这个例子对于嵌套超时、xhrs 和点击会更有趣。 blog.carbonfive.com/2013/10/27/… 作为您回答的附加信息非常有帮助。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-09-07
  • 2010-12-24
  • 2023-03-05
  • 2018-01-24
  • 2018-12-20
  • 1970-01-01
相关资源
最近更新 更多