我试图理解JavaScript中的事件循环是什么。遇到了Mozilla开发者网络关于事件循环的链接。
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/EventLoop
它提到
队列
JavaScript 运行时包含一个消息队列,该队列是要处理的消息。与每条消息相关联一个函数。当堆栈为空时,消息将从队列中取出,并且处理。处理包括调用关联的函数(从而创建初始堆栈帧)。消息处理当堆栈再次变为空时结束。
在此上下文中,消息队列是什么意思?它是指我们在浏览器中执行的每次点击或键盘事件吗?此事件中的每一个都是一条消息并添加到队列中?
请澄清。
术语"消息队列"几乎意味着它听起来的样子。它是要处理的消息队列(读取:要执行的事件回调),一次一个并按顺序处理。
这个"消息队列"不是 ECMAScript 的一部分,而是用来描述在单线程执行模型中处理异步事件的行为 - 每个浏览器事件(点击、计时器、AJAX 等)都被添加到队列中并以相同的方式处理。同样,node.js 使用事件进行异步 I/O 操作。
每当给定的全局上下文(即窗口或进程)没有执行 JavaScript 时,"消息队列"就会被处理到空(通过"事件循环")。这就是为什么阻塞 JavaScript 不好的原因 - 它将阻止队列被处理(从而阻止执行事件回调),直到阻塞代码停止执行。
node.js中的事件队列/事件循环的工作方式与浏览器相同,只是事件不同。这就是 node.js 在不公开多个线程和相关复杂性的情况下支持并发的方式。
将消息添加到此"消息队列"的代码的最常见方法之一是使用 setTimeout
- 当超时到期时,回调将添加到队列中。假设有一点善意的谎言(因为回调仅在事件实际发生时才添加到队列中),请考虑
setTimeout(f, 0)
setTimeout(g, 0)
将按顺序"排队"回调 f, g
setTimeout(f, 20) // MUST exceed time to g event firing
setTimeout(g, 0)
将回调序列"排队"g, f
。可以依赖这些序列保证,因为(setTimeout 保证和)添加到队列的消息/事件是按顺序处理的。
由于上面的代码正在运行(例如JavaScript正在执行),因此还可以保证在给定的JavaScript停止执行并且可以处理"消息队列"之前,不会调用f
和g
回调。但是,不能一般保证(在任何一种情况下)在f
和g
之间不会处理其他事件/回调。
每个 Javascript 实例都有一个事件队列(或消息队列)。一个节点.js实例有一个,一个浏览器每个窗口有一个(可能还有扩展等,但你明白了)。需要注意的关键是它们是独立的。虽然每次点击、键盘事件等都会发布到浏览器的 javascript 队列中,但它不会对节点实例的队列产生任何影响(当然,除非您在浏览器中编写了将这些事件代理回节点的事件处理程序,但这将是一个奇怪的情况)。希望这有助于澄清。如果我误解了你的问题,请告诉我。
您可能会发现我通过Bing搜索"可视化javascript事件循环"找到的此链接有助于广泛理解事件队列和事件循环概念,特别是如果您检查各种注释提供的一些进一步建议的阅读材料:http://blog.carbonfive.com/2013/10/27/the-javascript-event-loop-explained/