前端面试必考:JavaScript事件循环与任务队列详解

133 阅读1分钟

JavaScript执行顺序:同步任务 > 微任务 > 宏任务

宏任务与微任务的区别:

  • 微任务:在每个宏任务执行结束后立即执行,优先级高于宏任务
  • 宏任务:由宿主环境(如浏览器)发起的任务,包括事件回调、定时器等

常见的宏任务与微任务:

任务类型具体API
宏任务setTimeout、setInterval、I/O操作
微任务Promise.then、MutationObserver
⚠️渲染任务requestAnimationFrame(在浏览器渲染前执行,不属于宏任务/微任务)

练习

一个常见的执行顺序题目,输出打印结果顺序:

console.log('start');

setTimeout(() => {
  console.log('setTimeout 1');

  Promise.resolve().then(() => {
    console.log('Promise 2');

    setTimeout(() => {
      console.log('setTimeout 3');
    }, 0);
  });

}, 0);

Promise.resolve().then(() => {
  console.log('Promise 1');

  setTimeout(() => {
    console.log('setTimeout 2')
  }, 0);
});

console.log('end');

  1. 同步代码执行:

    • 输出 start
    • setTimeout1 加入宏任务队列
    • Promise1.then 加入微任务队列
    • 输出 end
  2. 检查微任务队列:

    • 执行 Promise1.then → 输出 Promise1
    • setTimeout2 加入宏任务队列
    • 微任务队列清空
  3. 取出第一个宏任务(setTimeout1):

    • 输出 setTimeout1
    • Promise2.then 加入微任务队列
  4. 再次检查微任务队列:

    • 执行 Promise2.then → 输出 Promise2
    • setTimeout3 加入宏任务队列
  5. 继续执行宏任务队列:

    • 执行 setTimeout2 → 输出 setTimeout2
    • 执行 setTimeout3 → 输出 setTimeout3

打印顺序为:

start  
end  
Promise 1  
setTimeout 1  
Promise 2  
setTimeout 2  
setTimeout 3