You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用async/await并发请求不丢结果,Promise.all失败如何保留其余结果?

如何用async/await发送并发请求且不丢失部分结果?

这个问题问得好!Promise.all的“全有或全无”特性确实会在单个请求失败时直接抛出错误,导致我们拿不到其他已经成功完成的请求结果,但完全不用退回到then().catch()的老语法,用纯async/await就能完美解决核心问题——让每个异步请求的Promise都始终处于fulfilled状态,哪怕它实际执行失败了。

核心思路

Promise.all只有当所有传入的Promise都fulfilled时才会返回成功结果,只要有一个rejected,它就会立即触发reject。所以我们要做的是给每个请求单独做错误兜底,让每个请求的Promise最终都返回一个包含“成功/失败状态”的对象,而不是直接reject。这样Promise.all就能收集到所有请求的结果,不管单个请求是否成功。

实现方案1:用包装函数统一处理(推荐,可复用)

我们可以写一个通用的包装函数,把任意异步请求(或async函数)包裹起来,用try/catch捕获错误,返回统一格式的结果对象:

// 模拟一个可能失败的异步请求
async function fetchResource(id) {
  if (id === 3) throw new Error(`资源 ${id} 不存在`);
  return { id, content: `资源内容 ${id}` };
}

// 通用包装函数:处理单个请求的成功/失败
async function wrapAsyncRequest(requestFn) {
  try {
    const data = await requestFn();
    return { success: true, data };
  } catch (error) {
    // 这里可以根据需求处理错误,比如只返回错误信息,或者保留完整Error对象
    return { success: false, error: error.message };
  }
}

// 并发请求的主函数
async function fetchAllResources() {
  // 准备所有要发送的请求,用包装函数包裹
  const requestList = [
    wrapAsyncRequest(() => fetchResource(1)),
    wrapAsyncRequest(() => fetchResource(2)),
    wrapAsyncRequest(() => fetchResource(3))
  ];

  // 用Promise.all并发执行,await获取所有结果
  const allResults = await Promise.all(requestList);

  // 按需分离成功和失败的结果
  const successfulResults = allResults.filter(item => item.success).map(item => item.data);
  const failedResults = allResults.filter(item => !item.success).map(item => item.error);

  console.log("成功获取的资源:", successfulResults);
  console.log("失败的请求:", failedResults);
}

fetchAllResources();

实现方案2:内联async函数(适合少量请求)

如果只是偶尔处理几个请求,不想单独写包装函数,也可以直接在Promise.all的数组里写内联的async函数,同样用try/catch兜底:

async function fetchAllResources() {
  const allResults = await Promise.all([
    (async () => {
      try {
        return { success: true, data: await fetchResource(1) };
      } catch (err) {
        return { success: false, error: err.message };
      }
    })(),
    (async () => {
      try {
        return { success: true, data: await fetchResource(2) };
      } catch (err) {
        return { success: false, error: err.message };
      }
    })(),
    (async () => {
      try {
        return { success: true, data: await fetchResource(3) };
      } catch (err) {
        return { success: false, error: err.message };
      }
    })()
  ]);

  // 后续处理和方案1一致
  const successfulResults = allResults.filter(item => item.success).map(item => item.data);
  const failedResults = allResults.filter(item => !item.success).map(item => item.error);

  console.log("成功获取的资源:", successfulResults);
  console.log("失败的请求:", failedResults);
}

为什么这两种方案都不用then/catch?

因为我们全程用async/await配合try/catch来处理错误,完全没有依赖then()和catch()链式调用的语法,既保持了代码的可读性,又解决了Promise.all丢结果的问题。

内容的提问来源于stack exchange,提问作者Carter

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.19 10:33:13