Promise.allSettled()

Запускаем несколько промисов параллельно и ждём, когда они все завершатся.

Время чтения: меньше 5 мин

Кратко

Скопировано

Метод allSettled() — это один из статических методов объекта Promise. Его используют, когда нужно запустить несколько промисов параллельно и дождаться их выполнения.

Promise.allSettled() очень похож на метод Promise.all(), но работает немного по-другому. В отличие от Promise.all(), Promise.allSettled() ждёт выполнения всех промисов, при этом неважно, завершились они успешно или с ошибкой.

Как пишется

Скопировано

Promise.allSettled() принимает итерируемую коллекцию промисов (чаще всего — массив) и возвращает новый промис, который будет выполнен, когда будут выполнены все переданные промисы. Полученный промис содержит массив результатов выполнения всех переданных промисов, сохраняя порядок оригинального массива, но не порядок выполнения.

Как понять

Скопировано

Создадим массив промисов и передадим его в Promise.allSettled(). Один из созданных промисов завершится ошибкой:

        
          
          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: 3 }    console.log(response2)    // { status: 'rejected', reason: 'error' }    console.log(response3)    // { status: 'fulfilled', value: 1 }})
          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: 3 }
    console.log(response2)
    // { status: 'rejected', reason: 'error' }
    console.log(response3)
    // { status: 'fulfilled', value: 1 }
})

        
        
          
        
      

Если промис выполнился успешно, то на выходе получаем объект с двумя свойствами — 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.allSettled() дождётся завершения всех запросов. Если же запросы зависимы, то лучше использовать метод Promise.all().

        
          
          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.allSettled() появился в спецификации языка недавно, а именно ES2020, возможно вам понадобится полифил.