Promise.any() 原理解析及使用指南
Promise.any(promises) 是 ES2021 新增的特性,它能够并行运行 promise,并解析为 promises 列表中第一个成功解析的 promise 的值。需要注意的是 Promise.any() 方法依然是实验性的,尚未被所有的浏览器完全支持。
下面来看看 Promise.any() 是如何工作的。
1.工作原理
Promise.any() 可用于以并行和竞争方式执行独立的异步操作,以获取任何第一个完成的 promise 的值。
该函数接受一个 promise 数组(通常为一个可迭代对象)作为参数,如下:
const anyPromise = Promise.any(promises);
当输入 promises 中的第一个 promise 被执行完成时,anyPromise 会立即解析为该 promise 的值。
但是,如果输入数组中的所有 promises 都被拒绝,或者输入数组为空,那么 Promise.any() 会 rejected 包含输入的 promises 执行的 rejection 错误原因集合。
2. 使用指南
现在来深入介绍一下 Promise.any(), 在这之前,先来定义 2 个简单的函数。
函数
resolveTimeout(value, delay)将返回一个在经过delay时间后有resolve的promise。
function resolveTimeout(value, delay) {
return new Promise((resolve) => setTimeout(() => resolve(value), delay));
}
函数
rejectTimeout(reason, delay)将返回一个在经过delay时间后有reject的promise。
function rejectTimeout(reason, delay) {
return new Promise((r, reject) => setTimeout(() => reject(reason), delay));
}
接下来使用上面定义的 2 个辅助函数来试试 Promise.any() 。
2.1 完成所有 promises
下面尝试运行第一个解析列表:
function resolveTimeout(value, delay) {
return new Promise((resolve) => setTimeout(() => resolve(value), delay));
}
function rejectTimeout(reason, delay) {
return new Promise((r, reject) => setTimeout(() => reject(reason), delay));
}
const fruits = ["potatoes", "tomatoes"];
const vegetables = ["oranges", "apples"];
const promise = Promise.any([
resolveTimeout(fruits, 1000),
resolveTimeout(vegetables, 2000),
]);
// 等待...
const list = async () => {
const result = await promise;
console.log(result);
};
// 1 秒之后
list(); // ['potatoes', 'tomatoes']
promise .any([…]) 返回一个在 1秒内 解析到数组 fruits 的 promise,因为解析 fruits 的 promise 先执行完成。
第二个是 2秒内 解析到数组 vegetables 的 promise,其值将被忽略。
2.2 一个 promise 被 rejected
将上面第一个 promise 出现异常被 rejected ,如下代码:
function resolveTimeout(value, delay) {
return new Promise((resolve) => setTimeout(() => resolve(value), delay));
}
function rejectTimeout(reason, delay) {
return new Promise((r, reject) => setTimeout(() => reject(reason), delay));
}
const vegetables = ["oranges", "apples"];
const promise = Promise.any([
rejectTimeout(new Error("fruits is empty"), 1000),
resolveTimeout(vegetables, 2000),
]);
// 等待...
const list = async () => {
const result = await promise;
console.log(result);
};
// 2 秒之后
list(); // [ 'oranges', 'apples' ]
上面的代码,第一个 promise 在 1秒后 被rejected,从执行的结果不难看出 Promise.any() 跳过了第一个被rejected的promise ,等待第二个 2秒后 执行完成的promise。
2.3 所有的 promises 被 rejected
下面来看下当所有的 promises 被 rejected 会出现什么结果,如下代码:
function rejectTimeout(reason, delay) {
return new Promise((r, reject) => setTimeout(() => reject(reason), delay));
}
const promise = Promise.any([
rejectTimeout(new Error("fruits is empty"), 1000),
rejectTimeout(new Error("vegetables is empty"), 2000),
]);
// 等待...
const list = async () => {
try {
const result = await promise;
console.log(result);
} catch (aggregateError) {
console.log(aggregateError);
console.log(aggregateError.errors);
}
};
list(); // [AggregateError: All promises were rejected]
从上面代码的执行结果来看,当所有输入promises 被 rejected 后, Promise.any([...]) 将返回一种特殊的错误 AggregateError 而被 rejected ,而详细的 rejected 原因在属性 aggregateError.errors 中 。
总结
Promise.any() 可用于以竞争方式并行执行独立的异步操作,以获取任何第一个成功执行完成的 promise 的值。如果 Promise.any() 的所有输入 promise 都被rejected 后,那么辅助函数返回的 promise 也会以错误集合的方式拒绝,该错误在一个特殊属性 AggregateError 中包含输入 promise 的拒绝原因:aggregateError.errors 。
本文文字及图片出自 InfoQ
你也许感兴趣的:
- Win1到Win11历届Windows图形界面:优劣与丑陋(排名)
- 你抽屉里断电的固态硬盘里的数据正在悄然丢失
- 台积电亚利桑那工厂停电 苹果芯片晶圆报废
- 编程语言 Rust 的几个核心问题
- 充气式空间站
- 由于视频编码算法H.265专利费上涨,戴尔和惠普部分机型暂停对其支持
- JavaScript中的错误链:借助Error.cause实现更清晰的调试
- PHP 8.5 新特性
- 说真的,我这次要装Linux了
- 对比安卓替代系统:Lineage OS、∕e∕OS 与 Graphene OS



你对本文的反应是: