В этом руководстве вы узнаете, как использовать статический метод Promise.all()
в JavaScript для агрегирования результатов нескольких асинхронных операций.
Статический метод Promise.all()
принимает итерацию промисов:
Promise.all(iterable);
Метод Promise.all()
возвращает один промис, который разрешается после разрешения всех входных промисов. Возвращенное обещание преобразуется в массив результатов входных обещаний:
На этой диаграмме promise1
разрешается в значение v1
в момент t1
, а promise2
разрешается в значение v2
в t2
. Следовательно, Promise.all(promise1, promise2)
promise2
обещание, которое разрешается в массив, содержащий результаты promise1
и обещаний2 [v1, v2]
в момент времени t2
.
Другими словами, Promise.all()
ожидает разрешения всех входных обещаний и возвращает новое обещание, которое разрешается в массив, содержащий результаты входных обещаний.
Если одно из входных промисов отклоняется, метод Promise.all()
немедленно возвращает промис, который отклоняется с ошибкой первого отклоненного промиса:
На этой диаграмме promise2
отклоняется в t1
времени 1 с error
. Поэтому Promise.all()
возвращает новое обещание, которое немедленно отклоняется с той же ошибкой. Кроме того, Promise.all() не заботится о других входных обещаниях, будут ли они разрешены или отклонены.
На практике метод полезен для агрегирования результатов нескольких асинхронных операций.
Примеры метода =
Давайте рассмотрим несколько примеров, чтобы понять, как работает метод Promise.all()
.
1) Пример решенных обещаний
Следующие обещания разрешаются в 10, 20 и 30 через 1, 2 и 3 секунды. Мы используем 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
Когда все промисы разрешены, значения из этих промисов передаются в обратный вызов метода then()
в виде массива.
Внутри обратного вызова мы используем метод reduce()
массива для вычисления общего значения и используем console.log
для отображения массива значений, а также общего количества.
2) Пример отклоненных обещаний
Promise.all()
возвращает обещание, которое отклоняется, если какое-либо из входных обещаний отклонено.
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
В этом примере у нас есть три обещания: первое разрешается через 1 секунду, второе отклоняется через 2 секунды и третье разрешается через 3 секунды.
В результате возвращенное обещание отклоняется, поскольку отклонено второе обещание. Метод catch()
выполняется для отображения причины отклоненного обещания.
Заключение
- Метод
Promise.all()
принимает список промисов и возвращает новое обещание, которое разрешается в массив результатов входных обещаний, если все входные обещания разрешены; или отклонить с ошибкой первого отклоненного промиса. - Используйте метод
Promise.all()
для агрегирования результатов нескольких асинхронных операций