好问题 👍
Promise.all 的特性是:只要有一个 Promise reject,整个 Promise.all 就会 reject,所以你看到的情况就是一个接口失败,整体就抛错了。
如果你的需求是:即使某个接口失败了,也希望其他成功的结果正常返回,有几种常见方案:
方案一:用 Promise.allSettled
从 ES2020 开始提供 Promise.allSettled,它会等待所有 Promise 都完成(无论成功还是失败),返回结果数组里包含每个 Promise 的状态和值:
javascript
const reqs = [
fetch("/api/1"),
fetch("/api/2"),
fetch("/api/3"),
];
Promise.allSettled(reqs).then(results => {
results.forEach((res, i) => {
if (res.status === "fulfilled") {
console.log("接口", i, "成功", res.value);
} else {
console.log("接口", i, "失败", res.reason);
}
});
});
返回结果类似:
lua
[
{ status: "fulfilled", value: ... },
{ status: "rejected", reason: ... },
{ status: "fulfilled", value: ... }
]
方案二:自己封装"永不 reject"的 Promise
如果你想继续用 Promise.all,可以把每个请求都 catch 一下,这样它们不会 reject:
less
function wrap(promise) {
return promise.then(
res => ({ status: "fulfilled", value: res }),
err => ({ status: "rejected", reason: err })
);
}
Promise.all([
wrap(fetch("/api/1")),
wrap(fetch("/api/2")),
wrap(fetch("/api/3")),
]).then(results => {
console.log(results);
});
效果和 allSettled 一样。
方案三:只需要成功的结果
如果你完全不关心失败的接口,只要成功的值,可以这样:
javascript
Promise.all([
fetch("/api/1").catch(() => null),
fetch("/api/2").catch(() => null),
fetch("/api/3").catch(() => null),
]).then(results => {
const validResults = results.filter(r => r !== null);
console.log("成功的结果:", validResults);
});
✅ 推荐:如果浏览器或 Node 环境支持,直接用 Promise.allSettled,最直观清晰。