Javascript事件循环说明

gwi*_*man 6 javascript event-loop

我一直看到"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...]
  }
Run Code Online (Sandbox Code Playgroud)

但我一直在看这样的解释(见下面的例子):

事件循环:

  1. 检查(Javascript)调用堆栈是否为空.

  2. 检查回调队列[AKA EventQueue]是否为空.

  3. 如果调用堆栈为空并且回调队列不为空,则:

    一个.将最旧的回调队列项出列.

    湾 将该回调函数推送到调用堆栈(并且没有提到调用该函数.)

  4. 保持循环.

这显然模糊地遵循我上面假设的模型,但有两个关键和令人不安的差异:

A.为什么事件循环需要检查JS调用堆栈是否为空?当然,每次循环时,调用堆栈都将处于相同的状态(无论是否完全"空"是在点之外 - 它不需要"检查").无论上次调用什么函数都会返回,恢复堆栈.所以那部分毫无意义.

B.为什么事件循环"将回调推送到JS堆栈"?事件循环不应该只是调用函数,从而创建一个合法的堆栈帧,以及从函数返回的方法,更不用说实际执行函数了吗?

所以我希望得到澄清,解释这些解释以及为什么它们实际上是正确的,或者支持我强烈怀疑它们是不正确的.


这些事件循环说明的示例来源:

菲利普罗伯茨:无论如何,事件循环到底是什么?在14:00 https://youtu.be/8aGhZQkoFbQ?t=839

打字稿高性能(书)第83页.

什么是Javascript事件循环? 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

Jon*_*ang 1

这是我对你的问题的回答:

JavaScript 以单线程和同步方式运行,因此事件回调函数将在全局执行上下文弹出执行堆栈后执行。所有的事件都会被添加到所谓的事件队列中。

当全局执行上下文完成所有执行后,JS引擎会不断检查事件队列中是否存在任何事件。如果 JS 引擎发现有一个事件,那么它会为回调函数创建一个新的执行上下文并将其推送到执行堆栈上。

在 JS 中,每次调用函数时,JS 引擎都会创建一个执行上下文,该上下文创建一个私有作用域,在该私有作用域中,无法从当前函数作用域外部直接访问函数内部声明的任何内容,并将执行推到顶部上下文堆栈。函数执行完毕后,执行上下文将被弹出。

  • 这是我对你的回答的评论 (2认同)