Skip to content
导航

事件循环

JavaScript 是单线程的:同时只能运行一个任务。

JavaScript 有一个基于事件循环的并发模型,事件循环负责执行代码、收集和处理事件以及执行队列中的子任务。

浏览器或其他用户代理,使用事件循环来协调事件、用户交互、脚本、渲染、网络等。每个用户代理都有唯一的事件循环。

消息队列

JavaScript运行时使用一个消息队列,存放待处理消息,每条待处理消息都有一个关联的处理消息的函数。

消息队列遵循先进先出的顺序,运行时会从最先进入队列的消息开始处理队列中的消息。
被处理的消息会被移出队列,并作为输入参数来调用与之关联的函数。

事件循环

之所以称之为 事件循环,是因为它经常按照类似如下的方式来被实现:

js
while (queue.waitForMessage()) {
  queue.processNextMessage();
}

每个事件循环都有一个或多个任务队列,又称宏任务队列。

以下任务属于宏任务:

  • 触发事件
  • HTML解析
  • 事件回调函数
  • 处理下载好的资源
  • DOM操作

当一个宏任务执行结束时,事件循环会检查是否有微任务需要执行。
如果有,它会依次执行所有的微任务,直到微任务队列为空。
然后,事件循环会检查是否有待处理的宏任务,并将它们推入宏任务队列中等待执行。

下面是所有提交微任务的方式:

  • Promise:通过 Promise 的 thencatchfinally 方法提交一个回调函数。
  • MutationObserver:通过 MutationObserver 的回调函数提交一个微任务。
  • queueMicrotask():HTML规范引入了一个新的 API,用于提交一个微任务。
  • process.nextTick(): Node.js可用的API,用于提交一个微任务。

参考资料