js宏任务和微任务执行顺序

220 阅读1分钟

1 - 同步和异步

  • js是一门单线程语言,在同一时间只能做一件事情

  • 同步任务会在主线程上执行,异步任务会进入任务队列,等待主线程任务执行完成后再将任务队列中的任务放入主线程执行

2 - 宏任务和微任务

异步任务又分为宏任务和微任务,宏任务会进入任务队列,而微任务不会进入任务队列,但微任务会等待同步任务执行完毕后执行

  • 宏任务:script(整体代码)、 setTimeout、 setInterval、ajax、事件绑定等
  • 微任务:Promise.then/.catch/.finally(promise本身是同步,只有.then或catch或finally才是异步)、process.nextTick(Node.js 环境)
一段script标签中宏任务和微任务的执行顺序为:

同步任务 -> 异步微任务 -> 异步宏任务


setTimeout(() => { console.info(1) }) // 异步宏任务 - 在异步微任务之后执行
Promise.resolve().then(() => { console.info(3) }) // 异步微任务 - 在同步任务后执行
console.info(2)  // 同步任务 - 优先执行

// 结果  2 - 3 - 1

console.info(1)

setTimeout(() => {
    Promise.resolve().then(() => {
        console.info(2)
    })
    console.info(3)
})

console.info(4)

new Promise((resolve) => {
    console.info(5)
    resolve()
}).then(() => {
    console.info(6)
})

setTimeout(() => {
    console.info(7)
    setTimeout(() => {
        console.info(8)
    })
})

console.info(9)

// 结果  1 - 4 - 5 - 9 - 6 - 3 - 2 - 7 - 8

上面这段代码中:

  1. 首先执行在主线程上的同步任务,即 1 4 5 9 (打印了5是因为Promise本身为同步,.then才是异步(微任务))
  2. 再去执行异步微任务 6
  3. 再执行第一任务队列异步宏任务(第一个setTimeout)3 2
  4. 再执行第二任务队列异步宏任务(第二个setTimeout)7
  5. 再执行第三任务队列异步宏任务(第三个setTimeout)8