我不断看到“Javascript 事件循环”(即:浏览器 JS 运行时事件循环)的解释,这些解释对我来说似乎不太合理,我希望有人能够提供一些权威的澄清。
我的基本假设是 JS 事件循环就像我们几十年来在 UI 框架中使用的事件循环一样,如下所示:
// [... some initialization ...]
// The Event Loop
while (true) {
if (! EventQueue.isEmpty()) {
event = EventQueue.pop_oldest_item();
event.callback(event [or some other kind of args]);
}
// [... defer to other non-JS tasks...]
}
但我不断看到这样的解释(参见下面的示例):
事件循环:
检查(Javascript)调用堆栈是否为空。
检查回调队列 [AKA EventQueue] 是否为空。
-
如果调用堆栈为空且回调队列不为空,则:
A。将最旧的回调队列项目出队。
b.将该回调函数推送到调用堆栈上(并且没有提及调用该函数。)
继续循环。
这显然模糊地遵循了我上面假设的模型,但有两个关键且令人不安的差异:
A. 为什么事件循环需要检查 JS 调用堆栈是否为空?当然,每次循环时,调用堆栈都将处于相同的状态(是否完全“空”不是重点——它不需要“检查”)。无论上次调用的函数都将返回,从而恢复堆栈。所以这部分没有意义。
B. 为什么事件循环会“将回调推送到 JS 堆栈上”?事件循环不应该只调用函数,从而创建一个合法的堆栈帧,以及从函数返回的方法,更不用说实际执行函数了?
因此,我希望能够澄清这些解释以及为什么它们实际上是正确的,或者增强我对它们不正确的强烈怀疑。
这些事件循环解释的示例来源:
Philip Roberts:事件循环到底是什么? 14:00https://youtu.be/8aGhZQkoFbQ?t=839 https://youtu.be/8aGhZQkoFbQ?t=839
Typescript 高性能(书籍)第 83 页。
什么是 JavaScript 事件循环?http://altitudelabs.com/blog/what-is-the-javascript-event-loop/ http://altitudelabs.com/blog/what-is-the-javascript-event-loop/
了解 Javascript 函数执行 - 调用堆栈、事件循环、任务等https://medium.com/@gaurav.pandvia/understanding-javascript-function-executions-tasks-event-loop-call-stack-more-part-1-5683dea1f5ec https://medium.com/@gaurav.pandvia/understanding-javascript-function-executions-tasks-event-loop-call-stack-more-part-1-5683dea1f5ec