事件循环不处理网络i/o,仅调度回调;网络请求由运行时底层完成,响应就绪后promise回调作为微任务加入队列,优先于宏任务执行;fetch返回的promise在响应头到达时resolve,但响应体解析(如res.json())需额外微任务。

JavaScript 的事件循环本身不直接处理网络请求响应,它只负责调度回调函数;真正的网络 I/O 由浏览器或 Node.js 运行时底层(如操作系统网络栈、libuv)完成,响应就绪后,相关回调(如 fetch().then()、XMLHttpRequest 的 onload)才被推入任务队列,等待事件循环在下一次空闲时执行。
网络请求是异步 I/O,不阻塞主线程
发起请求(如 fetch() 或 axios.get())时,JS 引擎立即返回一个 Promise,并把实际的网络操作交给运行时环境。主线程继续执行后续同步代码,不会等待服务器响应。
- 请求发送后,JS 立即进入下一个语句,Promise 处于 pending 状态
- 响应数据到达、HTTP 状态码和 headers 可读时,运行时触发“响应就绪”信号
- 此时,对应的
.then()或.catch()回调被包装成微任务(microtask),加入微任务队列
响应回调优先走微任务队列
现代浏览器和 Node.js 对基于 Promise 的网络 API(如 fetch)统一使用微任务机制调度成功/失败回调,因此它们总比 setTimeout 等宏任务更早执行。
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
-
fetch().then(() => console.log('done'))的回调属于微任务 - 若同时有
setTimeout(() => console.log('timeout'), 0),后者是宏任务,一定排在微任务之后 - 即使网络响应极快(如本地 mock),回调也不会在当前同步代码中立即执行,而是等本轮同步代码+所有微任务执行完后才触发
XMLHttpRequest 是特例:可配置为同步(但应避免)
XMLHttpRequest 支持 open(method, url, async) 的第三个参数设为 false,启用同步请求——这会阻塞主线程直到响应完成,彻底绕过事件循环。
- 同步 XHR 已被现代标准弃用,在新页面中禁用(会报错)
- 它破坏事件循环模型,导致 UI 冻结、无法响应用户输入,任何真实项目都不该使用
- 即便旧代码存在,也应替换为
fetch或 Promise 包装的 XHR
注意 fetch 的“响应体读取”也是异步的
fetch() 返回的 Promise 在收到响应头时就 resolve,但响应体(response.json()、response.text())仍需额外解析,且这些方法也返回 Promise。
-
fetch('/api').then(res => res.json())实际注册了两层微任务:第一层处理响应头,第二层处理 JSON 解析 - 如果响应体很大或解析复杂(如大 JSON),
res.json()的 resolve 时机可能明显滞后于fetch().then() - 不要误以为
fetch().then()执行就代表数据已可用;真正数据就绪在内层.then()中
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










