fetch请求发起同步,响应处理为微任务;其.then回调属Promise标准微任务,优先级高于setTimeout等宏任务,执行顺序为同步代码→微任务→宏任务。

fetch 请求本身是同步发起的,但它的响应处理(即 then、catch、await 后续逻辑)属于微任务。
fetch 的三阶段调度行为
理解 fetch 不是“一个任务”,而是一个跨阶段的异步操作链:
-
发起阶段(同步):调用
fetch(url)立即返回一个 Promise 对象,这一步完全同步,不进任何队列;此时请求已由浏览器网络线程接管,主线程继续执行后续代码。 - 响应就绪阶段(宏任务触发点):当 HTTP 响应头到达,浏览器底层将“响应可读”事件通知 JS 引擎,随后把 Promise 的 resolve/reject 回调排入微任务队列——注意:这不是宏任务,也不经过 setTimeout 那类队列。
-
回调执行阶段(微任务):当前宏任务(如 script 全局代码、click 处理函数等)执行完毕后,引擎立即清空微任务队列,
then()或await后续代码在此刻执行。
为什么 fetch.then 不是宏任务?
因为 fetch 基于 Promise 构建,而 Promise 的状态变更(fulfilled/rejected)所触发的 .then / .catch 是标准微任务。它和 Promise.resolve().then() 享有同一调度机制,优先级高于 setTimeout、UI 渲染、I/O 回调等宏任务。
举例验证:
当用户要求为 Java 代码添加注释、修改注释、审查注释、整理注释格式,或要求按照代码注释规范处理 Java 文件时,使用本技能。本技能用于统一生成和维护 Java 类注释模板、按 Git 对比 release 判断版本号、补充每行代码上方中文块注释、调整注释空行规则,并保持 Java 文件 UTF-8 无 BOM 编码。典型触发场景包括:补充类注释、更新 @version、检查 @author 来源、整理行尾注释、把注释放到代码上一行、检查注释是否符合规范、构建前检查 Java 注释风格。
立即学习“Java免费学习笔记(深入)”;
console.log('1');
fetch('/api').then(() => console.log('2'));
console.log('3');
输出一定是 1 → 3 → 2,说明 fetch.then 在同步代码结束后、下一个宏任务开始前执行。
与 XMLHttpRequest 的关键区别
XMLHttpRequest 的 onload 或 onreadystatechange 回调是宏任务(进入消息队列),而 fetch 的 then 是微任务。这意味着在相同场景下,fetch 的响应处理比 XHR 更快进入 JS 执行栈,延迟更低、更可预测。
实际开发中的调度影响
- 若需在 fetch 响应后强制让出主线程(比如避免长任务阻塞渲染),可用
setTimeout(() => { ... }, 0)把后续逻辑转为宏任务。 - 多个 fetch 并发时,它们的
then会按响应完成顺序依次加入微任务队列,但执行仍严格按加入顺序,不会因网络快慢乱序。 - 使用
await的 async 函数中,await 后代码本质也是微任务延续,所以await fetch(); console.log('done')中的 log 仍是微任务级别执行。

















