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

如何实现支持多类型Promise的allAndWait:仿Promise.all且等待全部完成

实现支持多类型Promise的allAndWait函数

要让allAndWait实现和Promise.all一致的类型体验,同时保持等待所有Promise执行完毕再抛出错误的逻辑,需要调整泛型定义以支持元组类型推断,具体实现如下:

function allAndWait<T extends readonly (PromiseLike<any> | any)[]>(values: T): Promise<{ [P in keyof T]: Awaited<T[P]> }> {
  return (async () => {
    const settledResults = await Promise.allSettled(values);
    
    // 找出第一个被拒绝的Promise
    const rejectedResult = settledResults.find(result => result.status === 'rejected') as PromiseRejectedResult | undefined;
    if (rejectedResult) {
      throw rejectedResult.reason;
    }
    
    // 将所有成功结果映射为对应类型的元组
    return settledResults.map(result => (result as PromiseFulfilledResult<any>).value) as { [P in keyof T]: Awaited<T[P]> };
  })();
}

关键修改点说明

  1. 泛型适配元组类型:
    原函数的泛型T仅支持单一类型的Promise集合,新定义的T extends readonly (PromiseLike<any> | any)[]允许输入包含不同类型Promise或直接值的元组,让TypeScript能准确推断返回值的元组类型,和Promise.all的行为完全对齐。

  2. 返回类型对齐Promise.all:
    使用{ [P in keyof T]: Awaited<T[P]> }作为返回类型,会将输入元组的每个元素通过Awaited解析为最终值类型,比如输入[Promise<number>, Promise<string>],返回类型就是Promise<[number, string]>。

  3. 兼容非Promise值:
    输入数组中可以直接传入非Promise类型的值(比如123、'test'),Promise.allSettled会自动将其视为已完成的Promise,函数会正确处理这类值的类型。

使用示例

// 正常场景:混合不同类型的Promise和直接值
async function successCase() {
  const result = await allAndWait([
    Promise.resolve(100),
    Promise.resolve('hello world'),
    true,
    new Promise<Date>(res => setTimeout(() => res(new Date()), 500))
  ]);
  // result类型为:[number, string, boolean, Date]
  console.log(result);
}

// 错误场景:等待所有Promise执行完毕后抛出第一个错误
async function errorCase() {
  try {
    await allAndWait([
      Promise.resolve(1),
      Promise.reject(new Error('任务失败')),
      new Promise(res => setTimeout(() => res(2), 1000))
    ]);
  } catch (err) {
    // 1秒后才会捕获到错误,因为第三个Promise需要执行完毕
    console.error(err.message); // 输出:任务失败
  }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.28 21:57:33