4

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

 3 years ago
source link: https://www.techug.com/post/promise-any-principle-analysis-and-use-guide.html
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

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 时间后有 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

本文文字及图片出自 InfoQ


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK