在现代 Web 开发中,异步操作已经成为不可避免的一部分。无论是从服务器获取数据,还是执行一系列耗时操作,我们都需要有效地管理这些异步任务。JavaScript 提供了多种处理异步操作的工具,Promise 是其中最常用的一种。而 Promise.allSettled 是一个强大的方法,特别适用于需要在所有操作完成后再进行处理的场景。
什么是 Promise.allSettled?
Promise.allSettled 是一个静态方法,它接受一个包含多个 Promise 对象的可迭代对象,并返回一个新的 Promise 对象。这个新的 Promise 对象会在所有传入的 Promise 都有结果后(无论成功还是失败)变为 fulfilled 状态,并返回一个数组。数组中的每一项都是一个结果对象,表示相应的 Promise 的状态和结果。
语法
Promise.allSettled(iterable);
- iterable:一个可迭代对象(一般是一个数组),其中每一项都是一个 Promise 对象。
返回值
Promise.allSettled 返回一个新的 Promise 对象,该对象在所有传入的 Promise 都有结果后变为 fulfilled 状态,并返回一个包含每个 Promise 结果对象的数组。每个结果对象包含以下两个属性:
- status:表示 Promise 的状态("fulfilled" 或 "rejected")。
- value:当状态为 "fulfilled" 时,包含 Promise 的返回值。
- reason:当状态为 "rejected" 时,包含 Promise 被拒绝的原因。
Promise.allSettled 和 Promise.all
共同点
- 并行执行多个异步操作:Promise.allSettled 和 Promise.all 都用于并行执行多个异步操作,它们接受一个包含多个Promise对象的可迭代对象(通常是数组)。
- 返回Promise对象:这两个方法都返回一个新的Promise对象,用于表示所有传入的Promise对象的整体完成状态。
区别
1. 处理结果的方式
- Promise.all:
- 如果所有传入的Promise对象都成功完成,返回的Promise对象会变为fulfilled状态,并返回一个包含所有成功结果的数组。
- 如果任何一个Promise对象失败,返回的Promise对象会立即变为rejected状态,并返回第一个失败的Promise的错误信息。
Promise.all([promise1, promise2, promise3])
.then((values) => {
console.log(values); // 所有Promise都成功时
})
.catch((error) => {
console.error(error); // 任何一个Promise失败时
});
- Promise.allSettled:
- 无论传入的Promise对象是成功还是失败,返回的Promise对象都会变为fulfilled状态。
- 返回的Promise对象会返回一个数组,数组中的每一项都是一个对象,表示每个Promise的结果对象,包含两个属性:
- status:字符串,表示Promise的状态("fulfilled"或"rejected")。
- value或reason:表示Promise成功的返回值或失败的原因。
Promise.allSettled([promise1, promise2, promise3])
.then((results) => {
console.log(results); // 无论所有Promise成功或失败
});
2. 错误处理的方式
- Promise.all:
- 一旦有一个Promise失败,整个Promise.all返回的Promise就会立即失败,并返回第一个失败的Promise的错误信息。
- 不会等待其他Promise完成。
- Promise.allSettled:
- 会等待所有Promise都完成(无论成功还是失败)。
- 不会因为某个Promise失败而影响整体结果,所有Promise的结果都会被收集并返回。
使用示例
示例1:所有 Promise 都成功完成
const promise1 = Promise.resolve(3);
const promise2 = new Promise((resolve) => {
setTimeout(resolve, 100, 'foo');
});
const promise3 = Promise.resolve(42);
Promise.allSettled([promise1, promise2, promise3]).then((results) => {
console.log(results);
// [
// { status: 'fulfilled', value: 3 },
// { status: 'fulfilled', value: 'foo' },
// { status: 'fulfilled', value: 42 }
// ]
});
在这个例子中,所有 Promise 都成功完成。Promise.allSettled 返回的 Promise 的状态会变为 fulfilled,并返回一个包含所有结果对象的数组,每个结果对象表示相应 Promise 的状态和结果。
示例2:其中一些 Promise 失败
const promise1 = Promise.resolve(3);
const promise2 = new Promise((resolve, reject) => {
setTimeout(reject, 100, 'error in promise2');
});
const promise3 = new Promise((resolve) => {
setTimeout(resolve, 200, 42);
});
Promise.allSettled([promise1, promise2, promise3]).then((results) => {
console.log(results);
// [
// { status: 'fulfilled', value: 3 },
// { status: 'rejected', reason: 'error in promise2' },
// { status: 'fulfilled', value: 42 }
// ]
});
在这个例子中,promise2 在 100 毫秒后失败,其余两个 Promise 成功。Promise.allSettled 返回的 Promise 的状态会变为 fulfilled,并返回一个包含所有结果对象的数组。