Watchman version 命令完全指南:查询版本号与能力协商(Capability Negotiation)
2026/9/22 11:39:04
你关注的宏任务、微任务执行顺序是前端面试的核心考点,尤其围绕setTimeout、Promise.then、async/await的执行逻辑,我会从概念定义、执行机制到经典例题,帮你彻底理清。
宏任务是浏览器 / Node.js 执行的大型异步任务单元,每次执行一个宏任务,执行完成后会先清空所有微任务,再进入下一个宏任务。
常见宏任务类型:
setTimeout、setInterval(定时器异步任务)setImmediate(Node.js 环境)requestAnimationFrame(浏览器环境)<script>标签中的同步代码,属于第一个宏任务)微任务是优先级更高的小型异步任务,会在当前宏任务执行完毕后、下一个宏任务执行前,被批量清空(按顺序执行所有微任务)。
常见微任务类型:
Promise.then()/Promise.catch()/Promise.finally()(Promise 状态改变后的回调)async/await中await后面的代码(本质是 Promise.then 的语法糖,属于微任务)process.nextTick(Node.js 环境,优先级高于普通微任务)MutationObserver(浏览器环境,监听 DOM 变化的回调)一句话总结:宏任务按队列排队执行,每个宏任务执行后,必先清空微任务队列,再执行下一个宏任务(微任务优先级 > 宏任务)。
async/await是 Promise 的语法糖,其执行顺序需重点掌握:
async修饰的函数,会返回一个 Promise 实例,函数内部同步代码正常执行;await关键字后面的表达式,会先同步执行(获取表达式结果);await会暂停当前函数的执行,将await后面的代码(即 “后续逻辑”)加入微任务队列(而非同步执行);await后面的 Promise 状态变为fulfilled后,微任务队列中的 “后续逻辑” 才会执行。示例验证:
async function testAsync() { console.log("1. await 前的同步代码"); await Promise.resolve("await 结果"); // await 后面的表达式同步执行 console.log("2. await 后的代码(微任务)"); } console.log("0. 全局同步代码"); testAsync(); console.log("3. 全局同步代码后续"); // 执行结果顺序:0 → 1 → 3 → 2 // 解析: // 1. 先执行全局同步代码:输出 0; // 2. 调用 testAsync,执行内部同步代码:输出 1; // 3. 执行 await 后面的 Promise.resolve(同步),然后将 console.log("2...") 加入微任务队列; // 4. 退出 testAsync,继续执行全局同步代码:输出 3; // 5. 当前宏任务(全局脚本)同步代码执行完毕,清空微任务队列:输出 2。console.log("1. 全局同步代码"); setTimeout(() => { console.log("4. setTimeout 宏任务"); }, 0); Promise.resolve() .then(() => { console.log("3. Promise.then 微任务"); }); console.log("2. 全局同步代码后续");1. 全局同步代码 2. 全局同步代码后续 3. Promise.then 微任务 4. setTimeout 宏任务setTimeout回调被加入「宏任务队列」;Promise.resolve()立即变为 fulfilled 状态,then回调被加入「微任务队列」;setTimeout回调执行:输出 4。console.log("1. 全局同步代码"); setTimeout(() => { console.log("6. setTimeout 宏任务1"); Promise.resolve().then(() => { console.log("7. setTimeout 内部的微任务"); }); }, 0); setTimeout(() => { console.log("8. setTimeout 宏任务2"); }, 0); async function asyncFunc() { console.log("2. async 内部同步代码"); await Promise.resolve(); console.log("5. await 后的微任务"); } asyncFunc(); Promise.resolve() .then(() => { console.log("4. 全局 Promise 微任务"); }); console.log("3. 全局同步代码后续");1. 全局同步代码 2. async 内部同步代码 3. 全局同步代码后续 4. 全局 Promise 微任务 5. await 后的微任务 6. setTimeout 宏任务1 7. setTimeout 内部的微任务 8. setTimeout 宏任务2asyncFunc,执行内部同步代码,输出 2;await Promise.resolve()同步执行后,将console.log("5...")加入微任务队列;Promise.resolve().then(...)将console.log("4...")加入微任务队列;Promise.then回调加入微任务队列,立即清空该微任务队列,输出 7;console.log("1. 全局同步代码"); async function async1() { await async2(); console.log("6. async1 await 后代码"); } async function async2() { console.log("2. async2 同步代码"); return Promise.resolve().then(() => { console.log("4. async2 返回的 Promise 微任务"); }); } async1(); Promise.resolve() .then(() => { console.log("5. 全局 Promise 微任务"); }); setTimeout(() => { console.log("7. setTimeout 宏任务"); Promise.resolve().then(() => { console.log("8. setTimeout 内部微任务"); }); }, 0); console.log("3. 全局同步代码后续");1. 全局同步代码 2. async2 同步代码 3. 全局同步代码后续 4. async2 返回的 Promise 微任务 5. 全局 Promise 微任务 6. async1 await 后代码 7. setTimeout 宏任务 8. setTimeout 内部微任务async1→ 执行await async2(),先调用async2;async2同步代码:输出 2 →return Promise.resolve().then(...),该then回调加入微任务队列;async2执行完毕,await等待其返回的 Promise 完成,将console.log("6...")加入微任务队列(需等async2的 Promise 微任务执行完才会触发);Promise.then回调加入微任务队列;async2内部的 Promise 微任务:输出 4;async1await 后的微任务:输出 6;setTimeout宏任务:输出 7 → 其内部 Promise 微任务立即执行,输出 8。Promise.then/catch/finally、async/await后续代码;setTimeout/setInterval、全局脚本、I/O 操作;await后面的表达式同步执行,后续代码进入微任务队列;