写点什么

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

用户头像
devpoint
关注
发布于: 刚刚
Promise.allSettled() 原理解析及使用指南

Promise 对象是 ECMAScript 6 中新增的对象,主要将 JavaScript 中的异步处理对象和处理规则进行了规范化。前面介绍了《Promise.any() 原理解析及使用指南》和《Promise.all() 原理解析及使用指南》,本文继续来介绍 Promise 另一个方法 Promise.allSettled(promises) ,返回一个在所有给定的 promise 都已经 fulfilledrejected 后的 promise ,并带有一个对象数组,每个对象表示对应的promise 结果。


下面来看看 Promise.allSettled() 是如何工作的。

1.工作原理

Promise.allSettled() 可用于并行执行独立的异步操作,并收集这些异步操作的结果。


函数接受一个 promise 数组(或通常是一个可迭代的)作为参数,如下:


const statusesPromise = Promise.allSettled(promises);
复制代码


当所有输入 promises 都被履行或拒绝时,statusesPromise 会解析为一个具有其状态的数组:


  • { status: 'fulfilled', value:value } : 如果相应的 promise 已经履行

  • { status: 'rejected', reason: reason } :如果相应的 promise 被拒绝



可以使用 then 方法提取所有 promises 的状态:


statusesPromise.then((statuses) => {    statuses; // [{ status: '...', value: '...' }, ...]});
复制代码


也可以使用 async/await 语法:


const statuses = await statusesPromise;
statuses; // [{ status: '...', value: '...' }, ...]
复制代码


Promise.allSettled() 返回的承诺总是以一系列状态实现,无论是否有一些(或者全部)输入承诺被拒绝。


Promise.allSettled()Promise.all() 的最大不同:Promise.allSettled() 永远不会被 rejected

2. 使用指南

现在来深入介绍 Promise.allSettled() 的使用之前, 还是先来定义 2 个简单的函数。


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));}
复制代码


接下来使用上面定义的 2 个辅助函数来试试 Promise.allSettled()

2.1 完成所有 promises

下面定义了一个 promise 数组 statusesPromise ,所有的 promise 都能够成功的 resolve 值,如下:


const fruits = ["potatoes", "tomatoes"];const vegetables = ["oranges", "apples"];
const statusesPromise = Promise.allSettled([ resolveTimeout(fruits, 2000), resolveTimeout(vegetables, 1000),]);
// 等待 2 秒 ...const list = async () => { try { const statuses = await statusesPromise; console.log(statuses); } catch (error) { console.log(error); }};
list(); // [{ status: 'fulfilled', value: [ 'potatoes', 'tomatoes' ] },{ status: 'fulfilled', value: [ 'oranges', 'apples' ] }]
复制代码


从上面执行的结果来看 Promise.allSettled() 返回的一个 promiseresolve 状态数组是按照执行前 statusesPromise 的顺序组成其结果。

2.2 一个 promiserejected

将上面第一个 promise 出现异常被 rejected ,如下代码:


const fruits = ["potatoes", "tomatoes"];
const statusesPromise = Promise.allSettled([ resolveTimeout(fruits, 2000), rejectTimeout(new Error("Vegetables is empty"), 1000),]);
// 等待 2 秒 ...const list = async () => { try { const statuses = await statusesPromise; console.log(statuses); } catch (error) { console.log(error); }};
list(); // // [{ status: 'fulfilled', value: ['potatoes', 'tomatoes'] },{ status: 'rejected', reason: Error('Vegetables is empty') }]
复制代码


即使输入数组中的第二个 promiserejectedstatusesPromise 仍然可以成功解析状态数组。

2.3 所有 promisesrejected

将上面所有的 promises 出现异常被 rejected ,如下代码:


const statusesPromise = Promise.allSettled([    rejectTimeout(new Error("Fruits is empty"), 2000),    rejectTimeout(new Error("Vegetables is empty"), 1000),]);
// 等待 2 秒 ...const list = async () => { try { const statuses = await statusesPromise; console.log(statuses); } catch (error) { console.log(error); }};
list(); // // [{ status: 'rejected', reason: Error('Fruits is empty') },{ status: 'rejected', reason: Error('Vegetables is empty') }]
复制代码

总结

当需要执行并行和独立的异步操作并收集所有结果时,Promise.allSettled() 就是不错的选择,即使一些异步操作可能失败。

发布于: 刚刚阅读数: 2
用户头像

devpoint

关注

细节的追求者 2011.11.12 加入

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

评论

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