promise.allsettled 更适合发多个请求,因为它会等待所有请求完成并返回每个请求的最终状态(fulfilled/rejected),而 promise.all 遇任一失败即中断;需避免在 fetch 后加 .catch(),并用 safefetch 封装处理 http 错误、超时和 json 解析,配合 abortcontroller 防止内存泄漏。

Promise.allSettled 为什么比 Promise.all 更适合发多个请求
因为 Promise.all 遇到任意一个请求失败(reject)就直接中断,整个调用返回失败;而真实业务中,你往往需要“不管成功失败,都要拿到每个请求的最终状态”——比如上报多个埋点、批量拉取不同接口的数据、做容错兜底。这时候必须用 Promise.allSettled。
怎么在 HTML 页面里发起并行请求并处理结果
直接在 <script></script> 标签里写即可,不需要额外框架或构建工具。关键点是:把每个 fetch 包装成 Promise,并确保它们不被意外 catch 掉(否则 allSettled 收不到 reject 状态):
const requests = [
fetch('/api/user'),
fetch('/api/order'),
fetch('/api/settings')
];
Promise.allSettled(requests)
.then(results => {
results.forEach((result, i) => {
if (result.status === 'fulfilled') {
result.value.json().then(data => console.log(`请求 ${i} 成功:`, data));
} else {
console.error(`请求 ${i} 失败:`, result.reason);
}
});
});
- 每个
fetch返回的是 Promise,但它的 resolve 值是Response对象,不是 JSON 数据 —— 所以得链式调用.json()(注意这步也返回 Promise,需再处理) - 不要在
fetch后面加.catch(),否则错误会被吞掉,allSettled看到的永远是 fulfilled - 如果后端响应非 2xx 状态码(如 404、500),
fetch默认仍算 fulfilled,需手动检查response.ok或response.status
如何统一处理 fetch 的状态和错误边界
裸写 fetch 容易漏掉网络失败、超时、JSON 解析失败等场景。建议封装一层,让每个请求返回真正“语义清晰”的 settled 结果:
function safeFetch(url, options = {}) {
return fetch(url, { ...options, signal: AbortSignal.timeout(8000) })
.then(res => {
if (!res.ok) throw new Error(`HTTP ${res.status}: ${res.statusText}`);
return res.json();
})
.catch(err => {
throw new Error(`[fetch] ${url}: ${err.message}`);
});
}
Promise.allSettled([
safeFetch('/api/user'),
safeFetch('/api/order'),
safeFetch('https://bad-domain.example/api/test') // 故意失败
]).then(results => {
results.forEach(r => {
if (r.status === 'fulfilled') console.log('✅', r.value);
else console.log('❌', r.reason.message);
});
});
- 用了
AbortSignal.timeout(8000)防止请求无限挂起(注意:部分旧浏览器不支持,可降级为AbortController+setTimeout) - 显式判断
res.ok把 HTTP 错误转为 reject,这样allSettled才能正确归类为 rejected - 错误 message 加了前缀,方便定位是网络层还是业务层问题
常见坑:DOM 操作时机和内存泄漏风险
如果你在请求完成后要更新页面元素(比如填充列表、显示加载态),要注意两点:
- 确保目标 DOM 节点还存在 —— 页面跳转、组件卸载后,
document.getElementById可能返回null,直接赋值会报错 -
Promise.allSettled不会自动取消已发出的请求,如果用户快速离开页面,这些 fetch 仍在后台运行,可能触发无意义的回调 - 建议配合
AbortController实现请求可取消,尤其在单页应用中切换路由时
最简单的防护写法:
const controller = new AbortController(); // ……传入 fetch 的 options.signal // 组件销毁/离开页面时调用 controller.abort()
没做这一步,看似功能正常,但在复杂交互下容易出现“数据更新到已销毁的 DOM”或“重复执行回调”这类隐蔽问题。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











