回调队列和事件队列有什么区别?

What is the difference between callback queue and event queue?

在一些关于JavaScript异步行为的在线资源中,也提到了浏览器架构、调用堆栈、事件循环和事件队列等概念。在描述浏览器事件循环的工作原理时,有些人使用 事件队列 一词,而其他人则使用 回调队列。我对这些术语感到困惑,想知道它们是否指代浏览器中使用的相同队列数据结构,或者它们是否不同并用于处理不同的场景?

图一-

图2-

在 HTML 的命名法(定义浏览器的事件循环)中,两者都不正确。

我们有"task-sources", which all may map to different task-queues.
event-loop processing, the User Agent will choose from which task-queue it will execute the next task. This task may itself fire events, or invoke callbacks.

开头

这些任务通过各种方式排队,或者作为其他任务的一部分(例如,在任务开始并行工作后,它会询问 queue a task 何时完成并行工作),或者来自 IPC直接消息(例如用户发起的事件)。

另请注意,事件循环的一部分会调用回调并直接由事件循环触发事件,而不是来自任务:Update the rendering
在那里你会发现一个 map of callbacks 和各种事件(滚动、调整大小、媒体查询等),它们被称为事件循环中这个特殊位置的一部分,它本身只偶尔被调用一次(通常当显示器发送垂直同步信号时)。

在回调队列中,任务大致分为两类,即微任务宏任务(通常称为任务)。

宏任务 在下列情况下被添加到宏任务队列:

  • 新的 JavaScript 程序或子程序被直接执行(例如从控制台,或通过 运行 元素中的代码)。
  • 事件触发,将事件的回调函数添加到宏任务队列。
  • 达到使用 setTimeout() 或 setInterval() 创建的超时或间隔,导致相应的回调被添加到任务队列。

microtask 是一个短函数,它在创建它的函数或程序退出后执行,并且只有在 JavaScript 执行堆栈为空时才执行,但在返回之前控制用户代理用来驱动脚本执行环境的事件循环。

微任务完全来自我们的代码。它们通常由承诺创建:.then/catch/finally 处理程序的执行成为微任务。微任务也在等待的“幕后”使用,因为它是承诺处理的另一种形式。

在文献中,您经常会看到他们将宏任务称为任务,将微任务称为作业。