JS事件循环探究(上)

macrotask(宏任务)

触发macrotask任务的操作包括:

  • dom事件回调,
  • ajax回调,
  • 定时器回调,
  • script(整体代码),
  • setTimeout、setInterval、setImmediate
  • I/O、UI交互事件
  • postMessage、MessageChannel

microtask(微任务)

触发microtask任务的操作包括:

  • Promise回调:Promise.then | (但Promise的resolve能够立即触发.then的执行)
  • Mutation回调:MutationObserver
  • process.nextTick(Node环境)

Event loop的执行顺序

  1. 执行同步代码,这属于宏任务 ,遇到异步代码,需要判断是放入宏任务队列还是微任务队列
  2. 执行栈为空,查询是否有微任务需要执行
  3. 执行所有微任务
  4. 必要的话渲染 UI
  5. 然后开始下一轮 Eventloop,执行宏任务中的异步代码(取出宏队列中排队的宏任务执行)

简单来说:每次开始执行宏任务之前,都要将微任务队列中的任务全部执行完毕

【例】

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
console.log("1");

setTimeout(function () {
console.log("2");
}, 0);

new Promise((resolve) => {
console.log("3");
resolve();
})
.then(function () {
console.log("4");
})
.then(function () {
console.log("5");
});

console.log("6");
// 执行结果:1 3 6 4 5 2

执行原理

image-20231101224357024