Javascript事件循环说明

问题描述:

我一直在看“解释JavaScript事件循环”(即:浏览器JS运行时事件循环),这对我来说似乎不太合理,我希望有人能提供一些权威性的说明。Javascript事件循环说明

我的基本asssumption是,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. 检查回调队列[AKA EventQueue]是否为空。

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

    一个。退出最旧的回调队列项目。

    b。将该回调函数推入调用堆栈(并没有提及调用该函数)。

  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

这是我回答你的问题:

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

在全局执行上下文完成所有执行后,JS引擎将继续检查事件队列内是否存在任何事件。如果JS引擎看到有一个事件,那么它会为回调函数创建一个新的执行上下文,并将其推送到执行堆栈上。在JS中,每次调用一个函数时,JS引擎都会创建一个执行上下文,它创建一个专用作用域,其中在该函数内部声明的任何东西都不能从当前函数作用域之外直接访问,并推入在执行上下文堆栈的顶部。在函数完成执行后,执行上下文将被弹出。

+0

这是我对你的回答的评论 – cambunctious

+0

我很感谢你回答,但我不知道这是如何解决我的问题。你肯定有一个事件队列 - 这是毫无疑问的。并且描述了一个函数调用的工作方式 - 就像任何涉及堆栈框架的语言一样(这里称为执行上下文)。还有一些关于弹出堆栈的Global Execution Context - 这是没有道理的。总之,你没有解决我的观点“A”和“B”。不过谢谢你的努力。 – gwideman