如何实现支持多类型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]> }; })(); }
关键修改点说明
泛型适配元组类型:
原函数的泛型T仅支持单一类型的Promise集合,新定义的T extends readonly (PromiseLike<any> | any)[]允许输入包含不同类型Promise或直接值的元组,让TypeScript能准确推断返回值的元组类型,和Promise.all的行为完全对齐。返回类型对齐Promise.all:
使用{ [P in keyof T]: Awaited<T[P]> }作为返回类型,会将输入元组的每个元素通过Awaited解析为最终值类型,比如输入[Promise<number>, Promise<string>],返回类型就是Promise<[number, string]>。兼容非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
相关产品推荐
相关产品推荐

