最常用且推荐的方式是使用 Promise.all() 配合 fetch;它并行发起请求,全部成功才 resolve,任一失败则 reject;需手动检查 response.ok;若需全部完成(含失败),改用 Promise.allSettled;大量请求时应限制并发数,可用并发池控制;旧环境可选 axios 并配合 AbortController 实现取消。

JavaScript 中处理并发 Ajax 请求并等待全部完成,最常用且推荐的方式是使用 Promise.all() 配合 fetch 或 XMLHttpRequest 封装的 Promise。它能自然地并行发起多个请求,并在全部成功时统一返回结果;任一失败则整体拒绝。
用 Promise.all + fetch 并发请求
现代浏览器中,fetch 返回 Promise,天然适配 Promise.all:
- 把所有请求包装成 Promise 数组(注意:
fetch(url)本身不 reject 网络错误以外的状态,需手动检查response.ok) -
Promise.all(promises)返回一个新的 Promise,只在所有请求 resolve 后才 resolve,任意一个 reject 就立即 reject - 如果需要“全部完成(含失败)”而非“全部成功”,改用
Promise.allSettled
示例:
HTTP ${res.status}
处理部分失败:用 Promise.allSettled
当需要知道每个请求的结果(无论成功或失败),而不是“全有或全无”,就用 Promise.allSettled:
- 它不会因某个请求失败而中断,始终等待所有 Promise 结束
- 返回数组,每个元素是
{ status: 'fulfilled' | 'rejected', value | reason } - 适合汇总统计、容错上报、降级展示等场景
示例:
Promise.allSettled(
urls.map(url => fetch(url).then(r => r.json()))
)
.then(results => {
const successes = results.filter(r => r.status === 'fulfilled').map(r => r.value);
const failures = results.filter(r => r.status === 'rejected').map(r => r.reason);
console.log('成功数', successes.length, '失败数', failures.length);
});
限制并发数量(避免过多请求压垮服务)
当请求数量很大(如 100 个)时,直接 Promise.all 可能触发浏览器连接数限制或服务端限流。可用“并发池”控制同时进行的请求数:
- 维护一个运行中的 Promise 队列,最多保持 N 个 pending
- 每次有 Promise settle 后,从待执行队列取下一个补位
- 可基于
async/await+for...of+ 信号量实现,或使用现成库如p-limit
简易实现(并发数 = 3):
async function runInParallel(tasks, limit = 3) {
const results = [];
const executing = [];
<p>for (const task of tasks) {
const p = task().then(res => res).catch(err => err);
results.push(p);</p><pre class="brush:php;toolbar:false;">if (limit executing.splice(executing.indexOf(e), 1));
executing.push(e);
if (executing.length >= limit) await Promise.race(executing);
}}
return Promise.all(results); }
兼容旧环境:用 axios 或封装 XMLHttpRequest
若需支持 IE 或需要自动重试、取消、拦截等功能,可用 axios:
- axios 本身返回 Promise,可直接用于
Promise.all - 提供
axios.all和axios.spread(已废弃,推荐直接解构数组) - 配合
AbortController可统一取消全部请求(现代方式)
示例:
const controller = new AbortController();
<p>Promise.all([
axios.get('/api/a', { signal: controller.signal }),
axios.get('/api/b', { signal: controller.signal })
])
.then(([a, b]) => { /<em> 处理 </em>/ })
.catch(err => {
if (err.name === 'CanceledError') console.log('已取消');
});</p><p>// 取消全部
controller.abort();</p>
不复杂但容易忽略:记得处理 HTTP 状态码、网络异常、超时和取消逻辑,单纯依赖 Promise.all 的“全成功”语义可能掩盖真实问题。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











