Ajax本质上就是异步请求,XMLHttpRequest和fetch默认异步执行,同步模式已被弃用;所谓“像同步”是因await或then显式等待,而非请求本身同步。

Ajax 本质上就是异步请求
不是“依赖”,而是“就是”。XMLHttpRequest(以及现代的 fetch)默认行为就是异步的——调用后立即返回,不阻塞后续 JS 执行,等响应回来再触发回调或 Promise resolve。
常见误解是以为 Ajax 可以“同步发送”,确实老式 XMLHttpRequest.open(method, url, async) 第三个参数设为 false 能强制同步,但已被现代浏览器弃用(尤其在主线程中),Chrome 会报 DeprecationWarning,Safari 直接拒绝执行。所以实际项目里,你写的每个 Ajax 都是异步的。
- 同步 Ajax 会冻结整个页面 UI,用户无法点击、滚动、输入,体验极差
- 即使强行启用,
fetch完全不支持同步模式,没有回退路径 - 所谓“同步效果”,应通过逻辑控制(如禁用按钮 + loading 状态 + then/catch 处理)来模拟,而非真同步
为什么有时感觉 Ajax “像同步”?
现象:连续发两个 fetch,第二个总在第一个完成后才发,代码看起来是“串行”的。这不是 Ajax 变同步了,而是你用了 await 或 .then() 显式等待前一个完成。
关键点在于控制流写法,不是请求本身:
-
fetch('/a').then(() => fetch('/b'))→ /b 等 /a 成功后再发 -
await fetch('/a'); await fetch('/b');→ 同上,更直观 -
fetch('/a'); fetch('/b');→ 两个并发发出,无依赖
错误做法是把多个请求塞进同一个回调里却不处理失败分支,导致后续请求永远不发——这容易被误认为“卡住了”,其实是逻辑没兜底。
并发请求太多时,浏览器会自动限流
不是 Ajax 或 JS 的问题,而是浏览器对同一域名的并发连接数做了限制(通常是 6~8 个)。超出的请求会排队,状态显示为 pending,直到有空闲连接。
这会让多个 fetch 看起来“变慢”甚至“顺序执行”,但它们仍是异步、并发发起的,只是被网络层拦了一下。
- 检查 Network 面板,看 pending 请求是否集中在同一 host
- 缓解方式:合并接口(如用一个
/batch接口代替多个单查)、分片请求、换子域名(需服务端配合) - 注意:HTTP/2 能复用连接,可缓解该问题,但不改变“Ajax 本身异步”的事实
真正要警惕的“伪异步”陷阱
最常踩的坑不是 Ajax 异不异步,而是忘了处理异步结果的副作用:比如在 fetch().then() 里更新 DOM,但组件已卸载(React/Vue 中常见),导致报错或内存泄漏。
- React 函数组件中,用
useEffect清理函数判断是否已 unmount - Vue 3
onBeforeUnmount中取消未完成的AbortController - 所有场景下,
fetch建议配signal,避免请求完成时上下文已失效
异步本身很可靠;不可靠的是我们常把“发了请求”当成“数据已就绪”,而忽略了中间存在时间差和状态不确定性。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











