我一直看到有关“Javascript事件循环”(即浏览器JS运行时事件循环)的解释,但这些解释似乎不可信,我希望有人能提供权威的澄清。
我的基本假设是,JS事件循环就像我们几十年来在UI框架中一直使用的事件循环,类似于:
但我一直看到像下面这样的解释(示例见下文):
事件循环:
1. 检查(Javascript)调用栈是否为空。 2. 检查回调队列[又称EventQueue]是否为空。 3. 如果调用栈为空且回调队列不为空,则: a. 出队最旧的回调队列项。 b. 将该回调函数推入调用栈(不提及调用该函数)。 4. 继续循环。
这显然模糊地遵循了我上述的假设模型,但有两个关键而令人困惑的差异:
A. 为什么事件循环需要检查JS调用栈是否为空?毕竟每次循环时,调用栈的状态都将相同(无论它是否完全“空”都无关紧要——它不需要“检查”)。上一次调用的任何函数都会返回,恢复堆栈。因此,这部分没有意义。
B. 为什么事件循环“将回调推入JS堆栈”?事件循环不应该只是调用函数,从而创建一个合法的堆栈帧和从函数返回的方法,更不用说实际执行函数了吗?
所以我希望能得到一个澄清,解释这些解释为什么是正确的,或者加强我非常怀疑它们不正确的观点。
这些事件循环解释的例子来源包括:
- Philip Roberts在14:00的"What the heck is the event loop anyway?"演讲,链接为https://youtu.be/8aGhZQkoFbQ?t=839。 - Typescript High Performance(书籍)第83页。 - "What is the Javascript event loop?",链接为http://altitudelabs.com/blog/what-is-the-javascript-event-loop/。 - "Understanding Javascript Function Executions - Call Stack, Event Loop, Tasks & more",链接为https://medium.com/@gaurav.pandvia/understanding-javascript-function-executions-tasks-event-loop-call-stack-more-part-1-5683dea1f5ec。
我的基本假设是,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...]
}
但我一直看到像下面这样的解释(示例见下文):
事件循环:
1. 检查(Javascript)调用栈是否为空。 2. 检查回调队列[又称EventQueue]是否为空。 3. 如果调用栈为空且回调队列不为空,则: a. 出队最旧的回调队列项。 b. 将该回调函数推入调用栈(不提及调用该函数)。 4. 继续循环。
这显然模糊地遵循了我上述的假设模型,但有两个关键而令人困惑的差异:
A. 为什么事件循环需要检查JS调用栈是否为空?毕竟每次循环时,调用栈的状态都将相同(无论它是否完全“空”都无关紧要——它不需要“检查”)。上一次调用的任何函数都会返回,恢复堆栈。因此,这部分没有意义。
B. 为什么事件循环“将回调推入JS堆栈”?事件循环不应该只是调用函数,从而创建一个合法的堆栈帧和从函数返回的方法,更不用说实际执行函数了吗?
所以我希望能得到一个澄清,解释这些解释为什么是正确的,或者加强我非常怀疑它们不正确的观点。
这些事件循环解释的例子来源包括:
- Philip Roberts在14:00的"What the heck is the event loop anyway?"演讲,链接为https://youtu.be/8aGhZQkoFbQ?t=839。 - Typescript High Performance(书籍)第83页。 - "What is the Javascript event loop?",链接为http://altitudelabs.com/blog/what-is-the-javascript-event-loop/。 - "Understanding Javascript Function Executions - Call Stack, Event Loop, Tasks & more",链接为https://medium.com/@gaurav.pandvia/understanding-javascript-function-executions-tasks-event-loop-call-stack-more-part-1-5683dea1f5ec。