写点什么

Promise.any() 原理解析及使用指南

用户头像
devpoint
关注
发布于: 2 小时前
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 的值。



可以使用 then 方法提取第一个 promise 的值:


anyPromise.then((firstValue) => {    firstValue; // 第一个 promise 完成后返回的值});
复制代码


也可以使用 async/await 语法:


const firstValue = await anyPromise;console.log(firstValue); // 第一个 promise 完成后返回的值
复制代码


Promise.any() 返回的 promise 与任何第一个执行的 promise 一起执行。即使某些 promiserejected,这些 rejections 也将会被忽略。



但是,如果输入数组中的所有 promises 都被拒绝,或者输入数组为空,那么 Promise.any()rejected 包含输入的 promises 执行的 rejection 错误原因集合。


2. 使用指南

现在来深入介绍一下 Promise.any(), 在这之前,先来定义 2 个简单的函数。


函数 resolveTimeout(value, delay) 将返回一个在经过 delay 时间后有 resolvepromise


function resolveTimeout(value, delay) {    return new Promise((resolve) => setTimeout(() => resolve(value), delay));}
复制代码


函数 rejectTimeout(reason, delay) 将返回一个在经过 delay 时间后有 rejectpromise


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秒内 解析到数组 fruitspromise,因为解析 fruits 的 promise 先执行完成。


第二个是 2秒内 解析到数组 vegetablespromise,其值将被忽略。

2.2 一个 promiserejected

将上面第一个 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' ]
复制代码


上面的代码,第一个 promise1秒后rejected,从执行的结果不难看出 Promise.any() 跳过了第一个被rejectedpromise ,等待第二个 2秒后 执行完成的promise

2.3 所有的 promisesrejected

下面来看下当所有的 promisesrejected 会出现什么结果,如下代码:


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]
复制代码


从上面代码的执行结果来看,当所有输入promisesrejected 后, Promise.any([...]) 将返回一种特殊的错误 AggregateError 而被 rejected ,而详细的 rejected 原因在属性 aggregateError.errors 中 。

总结

Promise.any() 可用于以竞争方式并行执行独立的异步操作,以获取任何第一个成功执行完成的 promise 的值。如果 Promise.any() 的所有输入 promise 都被rejected 后,那么辅助函数返回的 promise 也会以错误集合的方式拒绝,该错误在一个特殊属性 AggregateError 中包含输入 promise 的拒绝原因:aggregateError.errors


发布于: 2 小时前阅读数: 2
用户头像

devpoint

关注

细节的追求者 2011.11.12 加入

专注前端开发,用技术创造价值!

评论

发布
暂无评论
Promise.any() 原理解析及使用指南