宏任务和微任务

1.什么是宏任务和微任务

JavaScript把异步任务又做了进一步的划分,异步任务又分为两类,分别是:

  1. 宏任务(macrotask):

    • 异步Ajax请求
    • setTimeout 、setInterval
    • 文件操作
    • 其他宏任务
  2. 微任务(microtask):

    • Promise.then、Promise.catch和Promise.finally
    • process.nextTick
    • 其他微任务

2. 宏任务和微任务的执行顺序

宏任务和微任务_第1张图片

每一个宏任务执行完之后,都会检查是否存在待执行的微任务
如果有,则执行完所有的微任务之后,再执行下一个宏任务。
宏任务和微任务交替执行。

3. 利用情景加以理解

假设去银行办业务:

  1. A 和 B 去银行办业务。首先,需要取号之后进行排队

    • 宏任务队列
  2. 假设当前银行网点只有一个柜员,A 在办理存款业务时,B 只能等待

    • js单线程,宏任务按次序执行
  3. A 办完存款业务后,柜员询问他是否还想办理其他业务

    • 当前宏任务执行完,检查是否有微任务
  4. A 告诉柜员:想买理财产品,再办个信用卡(主业务办完后,又临时新增了一些业务去办理)

    • 执行微任务,后续宏任务被推迟
  5. A 离开柜台后,柜员开始为 B 办理业务

    • 所有微任务执行完毕,开始执行下一个宏任务

4. 分析以下代码的输出顺序

setTimeout(function() {console.log('1');})

new Promise(function(resolve) {
  console.log('2');
  resolve()
}).then(function() {
  console.log('3');
})

console.log('4');

正确的输出顺序是: 2 4 3 1

分析

宏任务和微任务_第2张图片

  1. 先执行所有的同步任务:输出 2 4
  2. 再执行微任务:输出 3(在执行宏任务之前,要先检查有没有未完成的微任务)
  3. 再执行下一个宏任务:输出 1

5. 经典面试题


console.log('1');

setTimeout(function() {
  console.log('2');
    new Promise(function(resolve) {
      console.log('3');
      resolve()
    }).then(function() {
      console.log('4');
    })
})

new Promise(function(resolve) {
  console.log('5');
  resolve()
}).then(function() {
  console.log('6');
})

setTimeout(function() {
  console.log('7');
  new Promise(function(resolve) {
    console.log('8');
    resolve()
  }).then(function() {
    console.log('9');
  })
})

正确输出顺序: 1 5 6 2 3 4 7 8 9

分析

宏任务和微任务_第3张图片
宏任务和微任务_第4张图片

宏任务和微任务_第5张图片

  1. 第一行中,同步任务
  2. A块中,这个定时器的回调函数属于异步任务里面的宏任务,一整个放入宏任务队列进行等待
  3. B块中,五属于同步任务,六属于微任务
  4. C块中,和A块一样,一整个放入宏任务队列
  5. 所以,先执行同步任务 1 5
  6. 再执行微任务 6,现在只剩下宏任务队列的两个任务了
  7. 会先执行A块,执行 2 3 4
  8. 再执行 C块,执行 7 8 9

你可能感兴趣的:(nodejs,JavaScript,javascript,前端)