Promise.any() 原理解析及使用指南
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.
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
Recommend
About Joyk
Aggregate valuable and interesting links.
Joyk means Joy of geeK