在本教程中,您将学习如何使用 Promise.all()
静态方法聚合来自多个异步操作的结果。
JavaScript Promise.all() 方法介绍
Promise.all()
静态方法接受一个可迭代的 Promise:
Promise.all(iterable);
Promise.all()
方法返回一个 Promise,当输入的所有 Promise 都已解决时,此 Promise 将解决。返回结果将会包含输入的 Promise 结果数组:
在此图中,promise1 在 t1 时解析为值 v1,而 promise2 在 t2 时解析为值 v2。 因此,Promise.all(promise1, promise2) 返回一个 promise,此 promise 解析为包含 promise1 和 promise2 结果的数组 [v1, v2] 在 t2 时。
换句话说,Promise.all()
等待输入的所有 Promise 解析并返回一个 Promise,Promise 解析为包含输入 Promise 结果的数组。
如果其中一个输入 Promise 被拒绝,Promise.all()
方法会立即返回一个拒绝的Promise ,并返回第一个被拒绝 Promise 的错误:
在此图中,promise2 在 t1 时因错误而拒绝。 因此,Promise.all() 返回一个新的 promise,它会立即拒绝并返回相同的错误。 此外,Promise.all() 不关心其他输入的 Promise,无论它们将解决还是拒绝。
在实践中,Promise.all()
聚合多个异步操作的结果很有用。
JavaScript Promise.all() 方法示例
让我们举一些例子来理解这个 Promise.all()
方法是如何工作的。
已解决的 Promise
以下 Promise 在 1、2 和 3 秒后解析为 10、20 和 30。我们使用 setTimeout()
来模拟异步操作:
const p1 = new Promise((resolve, reject) => {
setTimeout(() => {
console.log('The first promise has resolved');
resolve(10);
}, 1 * 1000);
});
const p2 = new Promise((resolve, reject) => {
setTimeout(() => {
console.log('The second promise has resolved');
resolve(20);
}, 2 * 1000);
});
const p3 = new Promise((resolve, reject) => {
setTimeout(() => {
console.log('The third promise has resolved');
resolve(30);
}, 3 * 1000);
});
Promise.all([p1, p2, p3]).then((results) => {
const total = results.reduce((p, c) => p + c);
console.log(`Results: ${results}`);
console.log(`Total: ${total}`);
});
输出
The first promise has resolved
The second promise has resolved
The third promise has resolved
Results: 10,20,30
Total: 60
当所有 Promise 都已解决时,这些 Promise 的值将作为数组传递到 then()
方法的回调。
在回调,我们使用 Array 的 reduce()
方法来计算总值并使用 console.log
来显示值数组和总计。
被拒绝的 Promise
如果任何输入 Promise 被拒绝,则 Promise.all()
返回一个被拒绝的 Promise。
const p1 = new Promise((resolve, reject) => {
setTimeout(() => {
console.log('The first promise has resolved');
resolve(10);
}, 1 * 1000);
});
const p2 = new Promise((resolve, reject) => {
setTimeout(() => {
console.log('The second promise has rejected');
reject('Failed');
}, 2 * 1000);
});
const p3 = new Promise((resolve, reject) => {
setTimeout(() => {
console.log('The third promise has resolved');
resolve(30);
}, 3 * 1000);
});
Promise.all([p1, p2, p3])
.then(console.log) // never execute
.catch(console.log);
输出:
The first promise has resolved
The second promise has rejected
Failed
The third promise has resolved
在这个例子中,我们有三个 Promise :第一个在 1 秒后被解决,第二个在 2 秒后被拒绝,第三个在 3 秒后被解决。
结果,返回的 Promise 被拒绝,因为第二个 Promise 被拒绝。执行 catch()
方法以显示拒绝 Promise 的原因。
结论
Promise.all()
方法接受 Promise 列表并返回一个新的 Promise,如果所有输入 Promise 都已解决,则该 Promise 将解析为输入 Promise 的结果数组。如果输入的 Promise 其中一个被拒绝,Promise.all()
返回的 Promise 也会被拒绝。- 使用
Promise.all()
方法聚合来自多个异步操作的结果。