Кратко
Секция статьи "Кратко"Метод all
— это один из статических методов объекта Promise
. Метод all
используют, когда нужно запустить несколько промисов параллельно и дождаться их выполнения.
Как пишется
Секция статьи "Как пишется"Promise
принимает итерируемую коллекцию промисов (чаще всего — массив) и возвращает новый промис, который будет выполнен, когда будут выполнены все промисы, переданные в виде перечисляемого аргумента, или отклонён, если хотя бы один из переданных промисов завершится с ошибкой.
Метод all
возвращает массив значений всех переданных промисов, при этом сохраняя порядок оригинального (переданного) массива, но не порядок выполнения.
Как понять
Секция статьи "Как понять"Успешное выполнение нескольких промисов
Секция статьи "Успешное выполнение нескольких промисов"Создадим несколько промисов
const promise1 = new Promise(resolve => setTimeout(() => resolve(1), 5000))const promise2 = new Promise(resolve => setTimeout(() => resolve(2), 2000))const promise3 = new Promise(resolve => setTimeout(() => resolve(3), 1000))
const promise1 = new Promise(resolve => setTimeout(() => resolve(1), 5000)) const promise2 = new Promise(resolve => setTimeout(() => resolve(2), 2000)) const promise3 = new Promise(resolve => setTimeout(() => resolve(3), 1000))
Передадим массив из созданных промисов в Promise
:
Promise.all([promise1, promise2, promise3]) .then(([response1, response2, response3]) => { console.log(response1) // 1 console.log(response2) // 2 console.log(response3) // 3 })
Promise.all([promise1, promise2, promise3]) .then(([response1, response2, response3]) => { console.log(response1) // 1 console.log(response2) // 2 console.log(response3) // 3 })
Если передать пустой массив, то Promise
будет выполнен немедленно.
Один из промисов завершился ошибкой
Секция статьи "Один из промисов завершился ошибкой"Если хотя бы один промис из переданного массива завершится с ошибкой, то Promise
тоже завершится с этой ошибкой. Метод уже не будет следить за выполнением оставшихся промисов, которые рано или поздно все-таки выполнятся, и их результаты будут просто проигнорированы.
В примере ниже, промис promise2
завершается с ошибкой:
const promise1 = new Promise(resolve => setTimeout(() => resolve(1), 5000))const promise2 = new Promise((resolve, reject) => setTimeout(() => reject('error'), 2000))const promise3 = new Promise(resolve => setTimeout(() => resolve(3), 1000))Promise.all([promise1, promise2, promise3]) .then(([response1, response2, response3 ]) => { console.log(response1) console.log(response2) console.log(response3) }) .catch(error => { console.error(error) // error })
const promise1 = new Promise(resolve => setTimeout(() => resolve(1), 5000)) const promise2 = new Promise((resolve, reject) => setTimeout(() => reject('error'), 2000)) const promise3 = new Promise(resolve => setTimeout(() => resolve(3), 1000)) Promise.all([promise1, promise2, promise3]) .then(([response1, response2, response3 ]) => { console.log(response1) console.log(response2) console.log(response3) }) .catch(error => { console.error(error) // error })
В итоге обработчик then
будет проигнорирован, и будет выполняться код из обработчика ошибок catch
.
Не промисы в массиве промисов
Секция статьи "Не промисы в массиве промисов"Если в Promise
передать не промисы, он вернёт переданные не промисы в массив результатов как есть (под капотом при этом произойдёт его преобразование с помощью метода Promise
).
Передадим в Promise
промис promise1
, число number
и объект obj
:
const promise1 = new Promise(resolve => setTimeout(() => resolve(1), 5000))const number = 2const obj = {key: 'value'}Promise.all([promise1, number, obj]) .then(([response1, response2, response3]) => { console.log(response1) // 1 console.log(response2) // 2 console.log(response3.key) // 'value' })
const promise1 = new Promise(resolve => setTimeout(() => resolve(1), 5000)) const number = 2 const obj = {key: 'value'} Promise.all([promise1, number, obj]) .then(([response1, response2, response3]) => { console.log(response1) // 1 console.log(response2) // 2 console.log(response3.key) // 'value' })
На практике
Секция статьи "На практике"🛠 Довольно частое использование — это преобразование массива с данными в массив с промисами с помощью map
. В map
для каждого элемента создаётся промис, а затем полученный массив передаётся в Promise
. Это позволит дождаться выполнения всех промисов, а затем обработать результат.
Например, можно использовать метод all
для получения данных нескольких персонажей из вселенной звёздных войн через запрос к API:
const peopleIds = [1, 13, 3]arrayFetchUsers = peopleIds.map(user => fetch(`https://swapi.dev/api/people/${user}`).then((response) => response.json()))Promise.all(arrayFetchUsers) .then((responses) => { // responses — массив результатов выполнения промисов responses.forEach(resp => { console.log(resp.name) }) }) .catch(error => { console.error(error) })
const peopleIds = [1, 13, 3] arrayFetchUsers = peopleIds.map(user => fetch(`https://swapi.dev/api/people/${user}`).then((response) => response.json())) Promise.all(arrayFetchUsers) .then((responses) => { // responses — массив результатов выполнения промисов responses.forEach(resp => { console.log(resp.name) }) }) .catch(error => { console.error(error) })
Пример сначала сделает три запроса к API, с помощью Promise
дождётся их завершения и парсинга ответа в JSON, а затем выведет имя персонажа для каждого. В консоли появится:
Luke Skywalker Chewbacca R2-D2