【问题标题】:Understanding execution model and event loop理解执行模型和事件循环
【发布时间】:2015-03-17 00:44:21
【问题描述】:

我已经阅读了很多关于 JavaScript 单线程执行模型、事件循环和事件队列的文章。

但有一点不清楚。我创建了一个小提琴来说明我的问题:http://jsfiddle.net/yzpmf67f/

<button onClick="window.compute()">Do computation</button>
<button onClick="alert('doing')">Do something else</button>

window.compute = function compute() {
var result = 0;
for (var i = 0; i < 100000; i++) {
    for (var j = 0; j < 100000; j++) {
        result = i + j;
    }
};
var textnode = document.createTextNode(result);
document.body.appendChild(textnode);

}

如果您单击“执行计算”按钮,则需要一些时间并阻止页面。但是如果你点击“做其他事情”按钮,当页面仍然挂起时,它仍然会被添加到队列中,并在我们的计算完成后执行。

那么,如果 JS 是单线程的,那么在我们计算其他内容的同时,谁将 UI 事件放入事件队列?

【问题讨论】:

  • 那么这个小提琴在哪里? :)
  • 对不起,由于缺少源代码,遇到了stackoverflow

标签: javascript event-loop


【解决方案1】:

那么,如果 JS 是单线程的,那么在我们计算其他内容的同时,谁将 UI 事件放入事件队列?

显然不是 JS :-) 它是浏览器中的其他线程之一,在这种情况下负责管理 UI 事件(这些事件又由操作系统提供)。事实上,有很多东西与 JS 引擎并行运行,例如管理网络连接(和排队 ajax 事件)的线程。

【讨论】:

  • 因此事件队列可以由我们的代码提供,例如,setTimeout() 或浏览器(I/O、UI 等)。对吗?
  • 是的,事件队列总是由一些异步后台操作提供。对于setTimeout,它将创建一个后台计时器对象,该对象会在一段时间后触发事件。
  • @damluar 是的。这种行为正在从网页领域转移到操作系统领域以及消息传递方式。在您的问题的情况下(至少在 Windows 上),它会将(除其他外)“鼠标按下”和“鼠标向上”事件传递给浏览器进行处理。当应用程序没有及时处理这些事件时,您就会得到“无响应”行为。这些 mousedown/mouseup 事件最终将由浏览器处理并转换为按钮上的单击事件。
  • 太棒了。感谢你们!还有一个问题。当我调用setTimeout(..., 2000)setTimeout(..., 1000) 函数时,第二个将首先触发,这很好。但我认为他们会按照执行顺序将 2 个事件添加到队列中。 JS 如何只用一个线程来处理这个问题?同样的问题是stackoverflow.com/questions/21718774,但没有解释为什么会这样。
  • @damluar 直到发生超时,事件才会被添加到队列中。脚本主机如何处理超时是一个实现细节(即它会因浏览器等而有所不同) - 只有当超时过去时,主机才会将回调放在执行队列中。
猜你喜欢
  • 1970-01-01
  • 2014-10-10
  • 2015-04-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-07-22
  • 2020-11-09
  • 2018-01-15
相关资源
最近更新 更多