浏览器中运行JavaScript的单线程概念

浏览器中运行JavaScript的单线程概念,javascript,asynchronous,dom-events,event-loop,Javascript,Asynchronous,Dom Events,Event Loop,下图摘自Jon Resig的书的第3章。在这里,作者将解释浏览器事件循环 这本书必须这样说: 需要注意的是,放置事件的浏览器机制 此事件循环模型的外部。加工 必须确定事件发生的时间并将其推到 事件队列不参与处理事件的线程 事件 所以我的问题是,说浏览器中的JavaScript是单线程的对吗?我问这个问题是因为显然有两个独立的任务(处理事件和事件查询在这里并行进行)。JavaScript在任何地方都是单线程的,无论是在浏览器中还是在NodeJ中。它从未被认为以任何方式支持多线程(如果有人用某种多

下图摘自Jon Resig的书的第3章。在这里,作者将解释浏览器事件循环

这本书必须这样说:

需要注意的是,放置事件的浏览器机制 此事件循环模型的外部。加工 必须确定事件发生的时间并将其推到 事件队列不参与处理事件的线程 事件


所以我的问题是,说浏览器中的JavaScript是单线程的对吗?我问这个问题是因为显然有两个独立的任务(处理事件和事件查询在这里并行进行)。

JavaScript在任何地方都是单线程的,无论是在浏览器中还是在NodeJ中。它从未被认为以任何方式支持多线程(如果有人用某种多线程实现JS引擎,肯定会发生不好的事情)

编辑以回答您的编辑:

该事件队列由来自浏览器主循环的数据(鼠标/kb事件、网络事件等)填充。运行JS的主循环。你发布的数字是正确的,但它(有点)模糊了现实。AFAIK只有一个线程处理所有事情(即,填充队列并逐行运行任何JS代码)

编辑:证明这一点的一种方法是:创建一个非常长的循环和一个文本区域。在循环运行时尝试写入文本。不能:这是因为主循环正忙于运行循环,因此无法处理kb事件

编辑:这似乎是一个非常好的答案:

+上次编辑2年后:这个答案变得有点陈旧,脱离了现实。io.js(以及之后的node.js,可能是Chrom[e|ium]、FF、Safari)正在推动多进程支持(通过workers)。您可以查看更多信息。

@alexanderst

证明这一点的一种方法是:创建一个非常长的循环和一个文本区域。尝试 在循环运行时写入文本。你不能:这是我的 因为主循环正忙于运行循环,所以无法处理 kb事件

这是因为事件循环无法处理事件。如果您等待循环完成,您会发现在循环运行时编写的所有文本都会出现


这意味着您有一个单独的线程来提取输入事件并将其放入队列。

使上述问题(可能)更有趣的可能是所谓的即时回调(如中所建议)的含义。简而言之,这样一个立即回调将是Javascript代码运行,而其他被阻塞语句(即
alert()
)暂停的代码尚未运行。由此看来,第二个任务“事件队列”可能会引入多线程问题(即确定性)。好问题!可能重复@alexandernst,因为您引用了这个问题,我想知道您是否愿意重新考虑“AFAIK[…]处理所有事情(即,填充队列并逐行运行任何JS代码)”的语句?流行语是“立即回调”,这一点在文章中很明智地提到了。你觉得怎么样?@humanityANDpeace确实是一本有趣的书。我真的不确定每个浏览器将如何处理这样一种情况:您正在运行一个很长的代码块,并立即启动回调。无论如何,有一件事我可以向你保证:如果你重复这个概念,肯定会适得其反。JS不允许运行任何类型的多线程/多进程/多线程等等。@alexandernst我做了进一步的检查。使用firefox,当我使用
alert()
停止某些执行时,我可以重现即时回调/事件的这种“无用”行为。我仍然怀疑这是否只是firefox的一个bug。你有没有碰巧读过规范来了解处理并发的“应该”方式?@humanityANDpeace没有。但我的猜测是,正版浏览器实际上不是暂停块中的一段代码的执行,只是因为立即回调激发。这样考虑:假设您设置了一个立即回调来更改一个全局变量,并且您还在一大块代码中使用该变量。如果在运行该代码块时更改了该全局变量的值,会发生什么情况?(回答:坏事)。@alexandernst我非常同意你的评论。我问了一个问题,想了解一下眼前发生的事情。我认为这是一个非常糟糕的想法,正如您所建议的那样,它会破坏可预测性或代码执行顺序。无论如何,作为一个firefox用户,我可以造成这样的破坏。想试试Firefox+这个(说明:在警报期间调整窗口大小)。我想知道我是否应该以及如何提交一个bug。