Promise.any 与 Promise.race区别

一、Promise.any

Promise.any 是 JavaScript 中用于处理多个 Promise 的方法,它会返回 第一个成功解析(fulfilled)的 Promise 的结果,只有当所有 Promise 都失败时才会抛出错误。

1.1、成功案例

const p1 = Promise.reject('Error1');
const p2 = new Promise(res => setTimeout(res, 500, 'Fast'));
const p3 = new Promise(res => setTimeout(res, 1000, 'Slow'));

Promise.any([p1, p2, p3])
  .then(console.log) // 'Fast'(500ms)
  .catch(e => console.log(e.errors)); // 不会执行

1.2、全失败案例

const errors = [
  Promise.reject('ErrorA'),
  Promise.reject('ErrorB')
];

Promise.any(errors)
  .catch(e => {
    console.log(e instanceof AggregateError); // true
    console.log(e.errors); // ['ErrorA', 'ErrorB']
  });

二、Promise.race

Promise.race 是 JavaScript 中用于处理多个 Promise 的竞速方法,它会返回 第一个完成(无论成功或失败)的 Promise 的结果

2.1、 首个成功完成的 Promise

const fast = new Promise(resolve => 
setTimeout(resolve, 100, '快速成功')
);

const slow = new Promise(resolve => 
setTimeout(resolve, 500, '慢速成功')
);

Promise.race([fast, slow])
.then(result => console.log(result)); // 100ms 后输出:"快速成功"

2.2、首个失败完成的 Promise

const success = new Promise(resolve => 
  setTimeout(resolve, 200, '成功')
);

const failure = new Promise((_, reject) => 
  setTimeout(reject, 100, '失败')
);

Promise.race([success, failure])
  .catch(error => console.log(error)); // 100ms 后输出:"失败"

三、使用场景

1. Promise.race 使用场景

场景特点
  • 需要 竞速,即优先响应第一个完成的结果(无论成功或失败)。
  • 适用于对响应速度敏感,且允许容忍部分失败的场景。

具体场景
1.1 超时控制

需求:为异步操作(如 API 请求)设置超时,避免长时间等待。
实现:将业务 Promise 与一个定时器 Promise 放入 race,若超时先完成,则中断操作。

const fetchData = () => {
  // 模拟数据请求(假设需要 3 秒)
  return new Promise((resolve) => 
    setTimeout(() => resolve("Data loaded"), 3000)
  );
};

// 设置 2 秒超时
const timeout = new Promise((_, reject) => 
  setTimeout(() => reject("Request timeout"), 2000)
);

Promise.race([fetchData(), timeout])
  .then(console.log)   // 若 2 秒内未完成,触发 timeout
  .catch(console.log); // 输出 "Request timeout"
1.2 多源竞速响应

需求:从多个数据源获取同一资源,优先使用最快响应的(无论成功与否)。
示例:两个天气 API 接口,选择最快返回的结果(可能是成功或失败)。

const api1 = fetch('https://weather-api1.com').then(r => r.json());
const api2 = fetch('https://weather-api2.com').then(r => r.json());

Promise.race([api1, api2])
  .then(data => displayWeather(data))
  .catch(() => showError("Failed to load weather"));

2. Promise.any 使用场景

场景特点
  • 需要 至少一个成功,忽略失败,直到第一个成功结果。
  • 适用于资源冗余、故障容忍的场景,优先保证可用性。

具体场景
2.1 多 CDN 资源加载

需求:从多个 CDN 加载静态资源(如 JS 库),使用第一个成功加载的。
实现:即使某些 CDN 不可用,也能通过其他备用源确保成功。

const cdnUrls = [
  'https://cdn1.example.com/react.js',
  'https://cdn2.example.com/react.js',
  'https://cdn3.example.com/react.js'
];

Promise.any(cdnUrls.map(url => 
  fetch(url).then(res => res.text())
))
.then(code => injectScript(code))
.catch(() => alert("All CDNs failed!"));
2.2 服务高可用(故障转移)

需求:调用多个备用服务(如支付网关),只要有一个成功即继续流程。
示例:用户支付时尝试多个支付渠道,直到有一个成功。

const paymentGateways = [
  payWithStripe(order),
  payWithPayPal(order),
  payWithAlipay(order)
];

Promise.any(paymentGateways)
  .then(receipt => showSuccess(receipt))
  .catch(errors => 
    alert(`All payments failed: ${errors.errors.join(', ')}`)
  );

四、总结

特性Promise.racePromise.any
关注点第一个完成的(无论成功或失败)第一个成功的(忽略失败,直到有成功)
成功时的行为返回第一个完成的结果(可能是成功或失败)返回第一个成功的结果
全失败时的行为返回第一个错误抛出 AggregateError(包含所有错误)
引入版本ES6 (ES2015)ES2021
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值