Кратко
СкопированоМетод all
— это один из статических методов объекта Promise
. Его используют, когда нужно запустить несколько промисов параллельно и дождаться их выполнения.
Promise
очень похож на метод Promise
, но работает немного по-другому. В отличие от Promise
, Promise
ждёт выполнения всех промисов, при этом неважно, завершились они успешно или с ошибкой.
Как пишется
СкопированоPromise
принимает итерируемую коллекцию промисов (чаще всего — массив) и возвращает новый промис, который будет выполнен, когда будут выполнены все переданные промисы. Полученный промис содержит массив результатов выполнения всех переданных промисов, сохраняя порядок оригинального массива, но не порядок выполнения.
Как понять
СкопированоСоздадим массив промисов и передадим его в Promise
. Один из созданных промисов завершится ошибкой:
const promises = [ new Promise(resolve => setTimeout(() => resolve(1), 3000)), new Promise((resolve, reject) => setTimeout(() => reject('error'), 2000)), new Promise(resolve => setTimeout(() => resolve(3), 1000))]Promise.allSettled(promises) .then(([response1, response2, response3]) => { console.log(response1) // { status: 'fulfilled', value: 1 } console.log(response2) // { status: 'rejected', reason: 'error' } console.log(response3) // { status: 'fulfilled', value: 3 }})
const promises = [ new Promise(resolve => setTimeout(() => resolve(1), 3000)), new Promise((resolve, reject) => setTimeout(() => reject('error'), 2000)), new Promise(resolve => setTimeout(() => resolve(3), 1000)) ] Promise.allSettled(promises) .then(([response1, response2, response3]) => { console.log(response1) // { status: 'fulfilled', value: 1 } console.log(response2) // { status: 'rejected', reason: 'error' } console.log(response3) // { status: 'fulfilled', value: 3 } })
Если промис выполнился успешно, то на выходе получаем объект с двумя свойствами — status
и value
. status
будет содержать строку 'fulfilled'
, а value
— значение, которое передали при вызове resolve
у промиса:
{ status: 'fulfilled', value: значение }
{ status: 'fulfilled', value: значение }
Если промис выполнился с отказом, то на выходе получаем объект с двумя свойствами — status
и reason
. status
будет содержать строку 'rejected'
, а reason
— значение, которое передали при вызове reject
у промиса:
{ status: 'rejected', reason: значение }
{ status: 'rejected', reason: значение }
На практике
Скопированосоветует Скопировано
🛠 Метод применяется для запросов к API. Он особенно удобен, когда запросы независимы и ошибка в одном не влияет на другие, так как Promise
дождётся завершения всех запросов. Если же запросы зависимы, то лучше использовать метод Promise
.
const urls = [ 'https://jsonplaceholder.typicode.com/todos/1', 'https://jsonplaceholder.typicode.org/i_need_an_error',]const arrayFetchData = urls.map(url => fetch(url).then(res => res.json()))Promise.allSettled(arrayFetchData) .then((res) => { // res — массив результатов выполнения промисов res.forEach(item => { console.log(item) }) })
const urls = [ 'https://jsonplaceholder.typicode.com/todos/1', 'https://jsonplaceholder.typicode.org/i_need_an_error', ] const arrayFetchData = urls.map(url => fetch(url).then(res => res.json())) Promise.allSettled(arrayFetchData) .then((res) => { // res — массив результатов выполнения промисов res.forEach(item => { console.log(item) }) })
В консоли получим:
// { status: 'fulfilled', value: { userId: 1, id: 1, ... } }// { status: 'rejected', reason: 'TypeError: Failed to fetch...' }
// { status: 'fulfilled', value: { userId: 1, id: 1, ... } } // { status: 'rejected', reason: 'TypeError: Failed to fetch...' }
🛠 Метод Promise
появился в спецификации языка недавно, а именно ES2020, возможно вам понадобится полифил.
На собеседовании
Скопировано отвечает
СкопированоТеория
СкопированоДля начала вспомним работу оригинального Promise
.
Он принимает коллекцию промисов, начинает одновременно их выполнять и возвращает массив результатов исполнения полученных промисов. Объект каждого результата содержит свойство status
. Если status
имеет значение fulfilled
(выполнено), то объект будет содержать свойство value
. Если status
имеет значение rejected
(отклонено), то объект будет содержать свойство reason
. Свойства value
или reason
будут содержать значение, с которым был выполнен или отклонён промис.
Подсказки
СкопированоСначала попробуйте решить самостоятельно. Если не получается, вот подсказки:
- Можно воспользоваться методом
Promse
.. all - Возвращаться должен массив с объектами.
- По завершению каждого промиса:
- если промис был выполнен, то запишем в поле
status
значениеfulfilled
, а в полеvalue
— результат выполнения промиса. - если промис был отклонён, то запишем в поле
status
значениеrejected
, а в полеreason
— значение с текущей ошибкой, по которой он был отклонён.
Решение
СкопированоНапишем код:
// На вход приходит массив промисовPromise.allSettled = (promises) => { // Запустим все промисы с помощью .all return Promise.all( promises.map((promise) => Promise.resolve(promise) // Если промис завершается успешно .then((value) => ({ status: "fulfilled", value })) // Если промис был отклонён .catch((e) => ({ status: "rejected", reason: e })) ) )}
// На вход приходит массив промисов Promise.allSettled = (promises) => { // Запустим все промисы с помощью .all return Promise.all( promises.map((promise) => Promise.resolve(promise) // Если промис завершается успешно .then((value) => ({ status: "fulfilled", value })) // Если промис был отклонён .catch((e) => ({ status: "rejected", reason: e })) ) ) }
Тесты
СкопированоТеперь протестируем наш полифил.
// Создадим несколько промисов для тестированияconst a = new Promise((resolve) => setTimeout(() => { resolve(3) },200))const b = new Promise((resolve,reject) => reject('error'))const c = new Promise((resolve) => resolve(5))// ВыполнимPromise .allSettled([a, b, c]) .then(console.log)/*[{status: 'fulfilled', value: 3},{status: 'rejected', reason: 'error'},{status: 'fulfilled', value: 5}]*/
// Создадим несколько промисов для тестирования const a = new Promise((resolve) => setTimeout(() => { resolve(3) },200)) const b = new Promise((resolve,reject) => reject('error')) const c = new Promise((resolve) => resolve(5)) // Выполним Promise .allSettled([a, b, c]) .then(console.log) /* [ {status: 'fulfilled', value: 3}, {status: 'rejected', reason: 'error'}, {status: 'fulfilled', value: 5} ] */