学习笔记--js的宏微任务和nodejs的宏微任务比较

0 阅读3分钟

JavaScript 宏任务 & 微任务 完整执行顺序(极简好记)

一、先记核心规则

  1. 同步代码 优先执行,从上到下跑完;
  2. 同步完 → 清空所有微任务(微任务一次性全清完);
  3. 微任务清空后 → 再取一个宏任务执行
  4. 循环往复:同步 → 微任务队列清空 → 单个宏任务 → 再微任务清空……

二、队列划分

宏任务(Macrotask)

优先级从高到低:

  1. script 整体代码(最先执行的整块 JS)
  2. setTimeout / setInterval
  3. I/O 操作、UI 渲染、Ajax

微任务(Microtask)

优先级高于宏任务:

  1. Promise.then/catch/finally
  2. async/await 后面代码
  3. queueMicrotask()
  4. MutationObserver

口诀:同先行,微全清,宏逐个

三、标准执行流程(一轮事件循环)

  1. 执行主线程同步代码
  2. 执行所有微任务队列(一次性全部执行完,不插队宏任务)
  3. 执行一个宏任务
  4. 回到第 2 步,继续清空微任务…… 无限循环

四、经典案例(直接背,面试必考)

console.log('同步1');

setTimeout(() => {
  console.log('宏任务 setTimeout');
}, 0);

Promise.resolve().then(() => {
  console.log('微任务 Promise.then');
});

console.log('同步2');

输出顺序:

  1. 同步 1
  2. 同步 2
  3. 微任务 Promise.then
  4. 宏任务 setTimeout

五、嵌套场景核心结论

  • 宏任务里创建的微任务:依然在当前宏任务执行完后,立刻清空微任务,再下一个宏任务。
  • 微任务里嵌套微任务:直接插队,跟着本轮微任务一起执行完。

六、最简背诵版

同步代码最先跑 → 所有微任务一次性清空 → 再跑一个宏任务 → 重复

Node.js 宏任务 & 微任务执行顺序(和浏览器完全不一样

我直接给你最清晰、最准确、能直接背的版本,区分 Node.js 11+ 新版本(现在主流) 和老版本,你只记新版本就行。


一、先记住:Node.js 和 Js 最大区别

  • Js:同步 → 清空所有微任务 → 执行一个宏任务
  • Node.js 新版本:同步 → 清空当前阶段微任务 → 执行同类型所有宏任务

简单说: Node 会把同一种宏任务一口气跑完,再去清空微任务


二、Node.js 宏任务分 6 个阶段(只记 3 个常用)

你不用全背,只记面试高频 3 种:

  1. timers 阶段setTimeoutsetInterval
  2. poll 阶段:I/O、文件、网络请求
  3. check 阶段setImmediate

执行顺序固定: timers → poll → check


三、Node.js 微任务(2 种,优先级不同)

Node 微任务分两类,优先级不一样

高优先级微任务(先执行)

  1. process.nextTick()
  2. Promise.then/catch/finally
  3. async/await 后面代码
  4. queueMicrotask

低优先级(几乎不用考)

  • MutationObserver(浏览器才有)

一句话: nextTick > 其他所有微任务


四、Node.js 完整执行顺序(终极版,直接背)

最终口诀(面试必过版)

同步代码优先 → nextTick 队列清空 → 其他微任务清空 → 同类型宏任务全部执行 → 再清空微任务 → 换下一类宏任务


五、最经典面试题(你一看就懂)

console.log('同步开始');

setTimeout(() => {
  console.log('setTimeout 1');
  Promise.resolve().then(() => {
    console.log('promise 1');
  });
}, 0);

setTimeout(() => {
  console.log('setTimeout 2');
  Promise.resolve().then(() => {
    console.log('promise 2');
  });
}, 0);

Promise.resolve().then(() => {
  console.log('promise 3');
});

process.nextTick(() => {
  console.log('nextTick');
});

console.log('同步结束');

输出结果(Node 11+)

  1. 同步开始
  2. 同步结束
  3. nextTick
  4. promise 3
  5. setTimeout 1
  6. promise 1
  7. setTimeout 2
  8. promise 2

为什么?

  • 先跑同步
  • 再跑 nextTick(最高优先级)
  • 再跑 其他微任务
  • 再把 所有 setTimeout 一口气跑完
  • 每跑完一个 setTimeout,立刻清空它产生的微任务

六、超级好记总结(3 句背会)

  1. 同步 > nextTick > 普通微任务
  2. 同类型宏任务会一口气全部执行
  3. 执行完一类宏任务,一定会清空当前微任务,再执行下一类宏任务

七、浏览器 vs Node.js 一句话区别

  • 浏览器:一个宏任务 → 清空微任务
  • Node.js:一类宏任务全跑完 → 清空微任务

需要我给你出 3 道进阶面试题,让你彻底练会不丢分吗?