返回
Promise.all与Promise.allSettled的对比和正确使用姿势
前端
2023-11-11 23:06:40
巧用Promise.all和Promise.allSettled应对异步编程的挑战
在JavaScript中,Promise是处理异步编程的利器。当我们需要等待多个异步操作同时完成时,Promise.all 和Promise.allSettled 可以大显身手。本文将深入探讨这两者的异同,助你应对异步编程的挑战。
语法:捕捉异步操作的结果
Promise.all(iterable) :接受可迭代对象,其中每个元素都是一个Promise。一旦所有传入的Promise完成,它返回一个新的Promise。若所有Promise成功,则新Promise解析为包含各个结果的数组;若有任何一个Promise被拒绝,则新Promise立即被拒绝,原因是第一个被拒绝的Promise的原因。
Promise.allSettled(iterable) :与Promise.all类似,但它无论传入的Promise是否被拒绝,始终解析。它返回一个数组,其中每个元素是一个对象,包含Promise的状态和结果。
执行顺序:控制并发性
Promise.all :按传入的顺序执行Promise。
Promise.allSettled :并发执行传入的Promise。
返回值:解析后的结果
Promise.all :所有Promise都成功解析,则解析为包含各个结果的数组;否则,被拒绝,原因是第一个被拒绝的Promise的原因。
Promise.allSettled :始终解析,返回一个包含Promise状态和结果对象的数组。
适用场景:根据需求选择
Promise.all :
- 需要等待所有异步操作同时完成
- 关心所有异步操作是否都成功完成
- 需要将所有异步操作的结果组合成一个数组
Promise.allSettled :
- 需要等待所有异步操作同时完成,但不关心是否都成功
- 需要获取所有异步操作的结果,即使有被拒绝的
代码示例:实践出真知
// Promise.all示例
const promise1 = new Promise((resolve, reject) => {
setTimeout(() => resolve('第一个Promise成功'), 1000);
});
const promise2 = new Promise((resolve, reject) => {
setTimeout(() => resolve('第二个Promise成功'), 2000);
});
const promise3 = new Promise((resolve, reject) => {
setTimeout(() => reject('第三个Promise失败'), 3000);
});
Promise.all([promise1, promise2, promise3])
.then((results) => console.log(results)) // ['第一个Promise成功', '第二个Promise成功', '第三个Promise失败']
.catch((error) => console.error(error)); // '第三个Promise失败'
// Promise.allSettled示例
const promise1 = new Promise((resolve, reject) => {
setTimeout(() => resolve('第一个Promise成功'), 1000);
});
const promise2 = new Promise((resolve, reject) => {
setTimeout(() => resolve('第二个Promise成功'), 2000);
});
const promise3 = new Promise((resolve, reject) => {
setTimeout(() => reject('第三个Promise失败'), 3000);
});
Promise.allSettled([promise1, promise2, promise3])
.then((results) => console.log(results));
// [{status: 'fulfilled', value: '第一个Promise成功'},
// {status: 'fulfilled', value: '第二个Promise成功'},
// {status: 'rejected', reason: '第三个Promise失败'}]
常见问题解答
-
两者有什么共同点?
- 都是处理多个异步操作的Promise方法
- 都返回一个Promise对象
-
两者最大的区别是什么?
- Promise.all关心所有Promise是否都成功,而Promise.allSettled不关心
-
什么时候应该使用Promise.all?
- 当我们需要等待所有异步操作都成功完成时
-
什么时候应该使用Promise.allSettled?
- 当我们需要等待所有异步操作完成,无论是否成功
-
如何处理被拒绝的Promise?
- Promise.all会立即被拒绝,原因是第一个被拒绝的Promise的原因;Promise.allSettled会返回一个包含被拒绝Promise状态和原因的对象