深入理解事件循环Event Loop(宏任务、微任务)

2024-06-18 00:22:25

浏览:70

评论:0

事件循环(Event Loop)是JavaScript异步编程模型的核心机制,它负责协调和调度不同的任务,确保它们能够有序、高效地执行。在JavaScript中,任务被分为两大类:宏任务(Macrotasks)和微任务(Microtasks)。

宏任务(Macrotasks)

主要包括:

  • Script(整体代码):整个脚本的执行就是一个宏任务。
  • setTimeout / setInterval
  • I/O(如文件读写、网络请求等)
  • UI渲染
  • setImmediate(Node.js环境)

微任务(Microtasks)

主要包括:

  • Promise的回调(.then/.catch/.finally)
  • MutationObserver(DOM变动监听)
  • process.nextTick(Node.js环境)
  • queueMicrotask(ES2019新增,用于替代process.nextTick或Promise.resolve().then()创建微任务的方式)

事件循环的流程

执行当前宏任务:JavaScript引擎首先执行当前的宏任务,包括同步代码和当前宏任务内的微任务。 执行微任务:在当前宏任务执行完后,开始执行当前宏任务产生的所有微任务,直到微任务队列为空。 渲染UI(可选):在某些环境下,如浏览器,此时有机会进行UI渲染。 检查是否有下一个宏任务:如果有,则重复上述过程,从第1步开始执行下一个宏任务;如果没有,则事件循环结束,等待新的任务到来。

举例说明

console.log('1');

setTimeout(function () {
  console.log('2');
  process.nextTick(function () {
    console.log('3');
  })
  new Promise(function (resolve) {
    console.log('4');
    resolve();
  }).then(function () {
    console.log('5')
  })
})
process.nextTick(function () {
  console.log('6');
})
new Promise(function (resolve) {
  console.log('7');
  resolve();
}).then(function () {
  console.log('8')
})

setTimeout(function () {
  console.log('9');
  process.nextTick(function () {
    console.log('10');
  })
  new Promise(function (resolve) {
    console.log('11');
    resolve();
  }).then(function () {
    console.log('12')
  })
})

// 执行结果为1,7,6,8,2,4,3,5,9,11,10,12