调用Promise.all()时如何为每个Promise附加自定义元数据?
实现方案
最简单的实现方式是给每个原始Promise加一层包装,让它在resolve时直接返回包含业务结果和对应元数据(flag)的对象,完全不需要修改Promise.all的调用逻辑,改动量极小。
方案1:直接改造getArrayOfPromises函数
调整函数内部逻辑,返回包装后的Promise数组,每个Promise最终resolve的结果都自带flag:
const getArrayOfPromises = () => { // 原有生成promise、flag的逻辑保持不变 return [ promise1.then(result => ({ result, flag: flag1 })), promise2.then(result => ({ result, flag: flag2 })), // 其余promise按相同规则包装 promisen.then(result => ({ result, flag: flagn })) ] }
原有调用逻辑仅需适配拿到的结果结构即可:
const arrayOfPromises = getArrayOfPromises(); Promise.all(arrayOfPromises).then(array => { array.forEach(item => { // item.result 为原始Promise的返回值 // item.flag 为绑定的对应标识 }) doStuff(array) })
方案2:兼容已有的对象数组返回逻辑
如果你已经完成了getArrayOfObjects的开发,不想改动该函数的实现,只需加一层数组转换即可:
const arrayOfObjects = getArrayOfObjects(); // 把对象数组转成包装后的Promise数组 const wrappedPromises = arrayOfObjects.map(({promise, flag}) => promise.then(result => ({ result, flag })) ); Promise.all(wrappedPromises).then(array => doStuff(array));
扩展支持异常场景
如果需要处理部分Promise rejected的场景,避免Promise.all整体中断,可以在包装时补充catch逻辑:
const wrappedPromise = promise .then(result => ({ success: true, result, flag })) .catch(err => ({ success: false, error: err, flag }))
方案优势
- 纯原生JS实现,无额外依赖,逻辑轻量
- Promise顺序和原始数组完全一致,不会出现flag和Promise对应错乱的问题
- 代码改动量极小,兼容原有业务逻辑
- 扩展性强,后续需要新增其他元数据只需在resolve的对象中补充字段即可
内容的提问来源于stack exchange,提问作者Steve Chambers
相关产品推荐
相关产品推荐

