我一直在看到对"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...]
}但我一直看到这样的解释(见下面的例子):
事件循环:
这显然是依循我上面假设的模型,但有两个关键和令人不安的区别:
为什么事件循环需要检查JS调用堆栈是否为空?当然,每次在循环中,调用堆栈都将处于相同的状态(无论是否完全“空”,它都不需要“检查”)。上一次调用的函数都将返回,恢复堆栈。所以这部分没有意义。
为什么事件循环“将回调推到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
发布于 2017-10-10 05:26:37
这是我对你问题的回答:
JavaScript以单线程和同步的方式运行,因此事件回调函数将在全局执行上下文弹出执行堆栈后执行。所有事件都将被添加到所谓的事件队列中。
在全局执行上下文完成所有执行之后,JS引擎将继续检查事件队列中是否存在任何事件。如果JS引擎看到有一个事件,那么它将为回调函数创建一个新的执行上下文,并将其推到执行堆栈上。
在JS中,每次调用函数时,JS引擎都将创建一个 execution context,它创建一个私有作用域,其中函数中声明的任何内容都不能从当前函数作用域之外直接访问,并推到执行上下文堆栈的顶部。函数完成执行后,执行上下文将被弹出。
发布于 2019-01-10 01:07:59
由于调用堆栈(事件处理程序、setTimeout、http请求)中执行的某些函数的异步性质,这些操作的消息(回调)可以随时添加到消息队列中。这可能发生在主线程仍在调用堆栈中运行函数时,因此事件循环需要检查它是否为空。一旦为空,它将从消息队列中提取下一条消息,并将其抛到调用堆栈中。这个循环构成了事件循环的本质。
我做了一个视频演示,解释并演示了这个过程:https://www.youtube.com/watch?v=4xsvn6VUTwQ
https://stackoverflow.com/questions/46658513
复制相似问题