在 ECMA International 发布的 ECMAScript 2020(ES11)中,新增了一个 Promise.allSettled() 方法。这个方法是 Promise.all() 方法的一种增强版,它允许在所有 promise 未必全部成功时,也能够处理所有 promise 的状态。
Promise.all() 的不足之处
在以前的 Promise 版本中,我们通常使用 Promise.all() 来处理多个 promise 对象的状态。比如,当我们需要发送多个 AJAX 请求并且在所有请求都成功响应后再执行某个方法时,我们通常会这么写:
// www.javascriptcn.com code example
Promise.all([
fetch(url1),
fetch(url2),
fetch(url3)
]).then(([res1, res2, res3]) => {
// 处理所有请求成功响应后的逻辑
}).catch((error) => {
// 处理请求异常的逻辑
});如上所示,Promise.all() 方法接受一个 promise 对象的数组作为参数,并在所有 promise 全部成功响应后,执行一个 callback 函数。但是,当 promise 对象数组中存在任意一个 promise 失败时,Promise.all() 方法立即 reject 并抛出错误。
这就意味着,如果我们的应用中某个 promise 请求失败了,整个页面都无法正常运行,而且没有任何提示或者错误信息,这是不能使用户体验提升的。
使用 Promise.allSettled() 完美解决上述问题
Promise.allSettled() 是 ECMAScript 2020 新增的一个方法,它是对 Promise.all() 方法的增强和完善。Promise.allSettled() 方法可以处理所有 promise 的状态,并返回一个包含所有 promise 状态的数组。
如下是 Promise.allSettled() 方法的语法:
Promise.allSettled(iterable);
参数 iterable 表示可迭代对象,比如数组等。它接受一个 promise 对象的数组作为参数,并返回一个包含所有 promise 对象的状态的数组,每个状态对象都有以下两个属性:
- status:表示 promise 对象的状态,有 "fulfilled" 和 "rejected" 两种状态
- value/reason:当 promise 对象的状态为 "fulfilled" 时,value 属性表示 promise 解决的值,否则 reason 属性表示 promise 拒绝的原因。
值得一提的是,Promise.allSettled() 方法必定执行完所有 promise 对象,并返回所有 promise 的状态,所以我们不必担心 Promise.all() 方法中存在的缺陷。
下面是一个使用 Promise.allSettled() 方法的例子:
// www.javascriptcn.com code example
Promise.allSettled([
fetch('/api/data1'),
fetch('/api/data2'),
fetch('/api/data3')
]).then(resList => {
resList.forEach(res => {
if (res.status === 'fulfilled') {
console.log(res.value);
} else {
console.log(res.reason);
}
});
});如上所示,在 Promise.allSettled() 方法返回的 resList 数组中,我们可以通过判断每个 promise 对象的状态来获取它们的返回值或者错误原因,从而达到检测所有 promise 对象的状态的目的。
恰当运用 Promise.allSettled() 是优化应用性能的好工具
Promise.allSettled() 方法是一种非常有用的优化工具,特别是对于那些需要改善应用性能和用户体验的场景。
下面是一个示例(使用 fetch 的场景):
// www.javascriptcn.com code example
let fetchHandles = [
fetch('/api/data1'),
fetch('/api/data2'),
fetch('/api/data3')
];
Promise.allSettled(fetchHandles).then(resList => {
let resCount = 0;
let resData = {};
resList.forEach(res => {
if (res.status === 'fulfilled') {
resData[resCount++] = res.value;
}
});
// 对 resData 变量进行后续处理...
});如上所示,我们可以在前端应用中使用 Promise.allSettled() 方法,将所有的 fetch 请求一起发出,然后通过循环获取所有的响应结果,并用一个对象存储。这种方式能够使我们的网络请求更加高效,并且可以提升用户体验。
需要注意的是,如果你的应用中包含多个独立的 promise 对象,并且你不想其中任何一个 promise 对象失败而导致整个应用错误,那么你非常有必要使用 Promise.allSettled() 方法。它能够帮助我们更完美地控制所有 promise 对象的状态,并且通过遍历返回的状态数组,可以获得更多的可操作信息。
结语
Promise.allSettled() 是 ECMAScript 2020 新增的一个方法,它能够帮助我们在多个 promise 对象的场景下,更好的掌控所有 promise 对象的状态。它是对 Promise.all() 方法的一种增强和完善,能够大大提升我们应用的性能和用户体验。使用它之前,我们需要了解它的语法和使用方法,从而充分发挥它的作用。
来源:JavaScript中文网 ,转载请注明来源 https://www.javascriptcn.com/post/67d622d5a941bf7134bc88f8