如何使Promise.race在最快Promise拒绝时继续执行直至获取成功结果?
实现容错的Promise竞态处理
要解决「最快完成的Promise拒绝时,继续等待下一个成功Promise」的问题,核心思路是忽略已拒绝的Promise,直到找到第一个成功完成的Promise,以下是两种实用方案:
方案一:手动递归过滤失败Promise
通过包装Promise标记状态,递归对剩余未失败的Promise执行竞态,直到拿到成功结果:
function raceUntilSuccess(promises) { const remaining = [...promises]; if (remaining.length === 0) { return Promise.reject(new Error('所有请求均失败')); } return Promise.race( remaining.map(p => p.then(res => ({ success: true, res })) .catch(() => ({ success: false, promise: p })) ) ).then(outcome => { if (outcome.success) { return outcome.res; } // 移除已失败的Promise,继续竞态剩余请求 remaining.splice(remaining.indexOf(outcome.promise), 1); return raceUntilSuccess(remaining); }); } // 使用示例 const myPromises = [p1, p2, p3]; raceUntilSuccess(myPromises) .then(winner => console.log('第一个成功的结果:', winner)) .catch(err => console.log('所有请求都失败了:', err));
方案二:使用ES2021+的Promise.any
ES2021新增的Promise.any原生支持该需求:它会直接返回第一个成功完成的Promise结果,自动忽略已拒绝的Promise;仅当所有Promise都拒绝时,才抛出包含所有失败原因的AggregateError。
const myPromises = [p1, p2, p3]; Promise.any(myPromises) .then(winner => console.log('第一个成功的结果:', winner)) .catch(err => console.log('所有请求都失败了:', err));
与
Promise.race的核心区别:
Promise.race返回第一个完成的Promise(无论成功/失败)Promise.any返回第一个成功的Promise(跳过所有已拒绝的)
场景验证
p1率先完成但返回500状态码导致Promise拒绝
p2第二个完成且返回200状态码,应返回p2
上述两种方案都会自动跳过拒绝的p1,最终返回p2的成功结果。
内容的提问来源于stack exchange,提问作者user38643
相关产品推荐
相关产品推荐

