事件循环
JavaScript 是单线程的:同时只能运行一个任务。
JavaScript 有一个基于事件循环的并发模型,事件循环负责执行代码、收集和处理事件以及执行队列中的子任务。
浏览器或其他用户代理,使用事件循环来协调事件、用户交互、脚本、渲染、网络等。每个用户代理都有唯一的事件循环。
消息队列
JavaScript运行时使用一个消息队列,存放待处理消息,每条待处理消息都有一个关联的处理消息的函数。
消息队列遵循先进先出的顺序,运行时会从最先进入队列的消息开始处理队列中的消息。
被处理的消息会被移出队列,并作为输入参数来调用与之关联的函数。
事件循环
之所以称之为 事件循环,是因为它经常按照类似如下的方式来被实现:
js
while (queue.waitForMessage()) {
queue.processNextMessage();
}
每个事件循环都有一个或多个任务队列,又称宏任务队列。
以下任务属于宏任务:
- 触发事件
- HTML解析
- 事件回调函数
- 处理下载好的资源
- DOM操作
当一个宏任务执行结束时,事件循环会检查是否有微任务需要执行。
如果有,它会依次执行所有的微任务,直到微任务队列为空。
然后,事件循环会检查是否有待处理的宏任务,并将它们推入宏任务队列中等待执行。
下面是所有提交微任务的方式:
Promise
:通过 Promise 的then
、catch
、finally
方法提交一个回调函数。MutationObserver
:通过 MutationObserver 的回调函数提交一个微任务。queueMicrotask()
:HTML规范引入了一个新的 API,用于提交一个微任务。process.nextTick()
: Node.js可用的API,用于提交一个微任务。