Skip to main content

Promise.allSettled() у JavaScript

Promise.allSettled() це статичний метод, який приймає масив (або інший ітерований об'єкт) промісів і повертає новий проміс, що виконується, коли всі передані проміси завершаться. Не має значення, чи завершились вони успішно (fulfilled), чи з помилкою (rejected): метод чекає на усі результати, а не лише на успішні.

Теорія

TL;DR

  • Promise.allSettled(iterable) чекає, поки всі проміси завершаться будь-яким чином.
  • Повернений проміс завжди переходить у стан fulfilled, він не відхиляється ніколи.
  • Значення це масив об'єктів {status, value} або {status, reason} у порядку входу.
  • Promise.all() натомість відхиляється на першому ж reject і губить решту результатів.
  • Типове застосування: масове завантаження даних, паралельна валідація, пакетне надсилання запитів.

Швидкий приклад

javascript
const p1 = Promise.resolve('Успішно'); const p2 = Promise.reject('Помилка'); const p3 = Promise.resolve('Ще одне'); Promise.allSettled([p1, p2, p3]) .then(results => console.log(results));

Вивід:

javascript
[ { status: "fulfilled", value: "Успішно" }, { status: "rejected", reason: "Помилка" }, { status: "fulfilled", value: "Ще одне" } ]

Усі проміси завершились, метод не «впав», а повернув повне зведення: хто виконався, а хто впав.

Синтаксис:

javascript
Promise.allSettled(iterable)

Повертає новий проміс, який завжди переходить у стан fulfilled і віддає масив об'єктів з результатами.

Структура результату

Кожен елемент масиву це об'єкт з однаковим набором полів:

ПолеКоли з'являєтьсяЗначення
statusзавжди"fulfilled" або "rejected"
valueякщо fulfilledрезультат проміса
reasonякщо rejectedпричина помилки

Порядок елементів відповідає порядку вхідних промісів, тому результат легко зіставити з початковим списком за індексом.

Коли використовувати Promise.allSettled()

  • Коли важливо дочекатися завершення всіх операцій, навіть якщо частина з них завершиться з помилкою.
  • Коли потрібно зібрати всі результати та помилки разом, в одному звіті.
  • Наприклад, при масовому завантаженні даних, паралельній валідації, пакетному надсиланні запитів, очищенні даних тощо.

Відмінність від Promise.all()

ХарактеристикаPromise.all()Promise.allSettled()
Коли завершитьсяТільки якщо всі проміси успішніКоли всі проміси завершаться (з будь-яким результатом)
Що повертаєМасив значень valueМасив об'єктів {status, value/reason}
Поведінка при помилці«Падає» на першому ж rejectНе падає, чекає на всіх
Стан поверненого промісаМоже бути fulfilled або rejectedЗавжди fulfilled
Для чого використовуютьКоли важливо, щоб усе пройшло успішноКоли важливо отримати звіт про всі результати

Приклад порівняння:

javascript
const a = Promise.resolve('A'); const b = Promise.reject('Помилка'); const c = Promise.resolve('C'); // Promise.all Promise.all([a, b, c]) .then(console.log) .catch(err => console.error('Promise.all:', err)); // Promise.allSettled Promise.allSettled([a, b, c]) .then(console.log);

Вивід:

javascript
Promise.all: Помилка [ { status: 'fulfilled', value: 'A' }, { status: 'rejected', reason: 'Помилка' }, { status: 'fulfilled', value: 'C' } ]

Promise.all() зупинився на помилці, а Promise.allSettled() дочекався всіх і повернув повний звіт.

Практичний приклад

Уявіть, що потрібно завантажити дані з кількох джерел, і навіть якщо одне недоступне, решта все одно потрібні:

javascript
const urls = ['/user', '/posts', '/comments']; const requests = urls.map(url => fetch(url)); Promise.allSettled(requests) .then(results => { results.forEach((res, i) => { if (res.status === 'fulfilled') { console.log(`${urls[i]}: OK`); } else { console.warn(`${urls[i]}: помилка`); } }); });

Так ви отримуєте підсумок по всіх запитах, навіть якщо один із них «впав».

Проста аналогія:

Уявіть, що ви замовили три доставки:

  • Promise.all(): якщо хоча б одна доставка не дійшла, ви одразу засмучуєтесь і не чекаєте на решту.
  • Promise.allSettled(): ви чекаєте на всіх кур'єрів, навіть якщо хтось прийшов без посилки, щоб знати, що сталося з кожною доставкою.

Підсумкова таблиця:

МетодПоведінка при помилціЩо повертаєКоли завершиться
Promise.all()«Падає» на першому rejectМасив успішних значеньКоли всі успішні
Promise.allSettled()Не «падає» ніколиМасив {status, value/reason}Коли всі завершені

Типові помилки

  • Чіпляти .catch() і чекати, що він спрацює. Проміс від allSettled() не відхиляється, тому помилки треба шукати в елементах масиву зі status === 'rejected', інакше збій пройде непоміченим.
  • Плутати value і reason. У відхиленого елемента немає value, у виконаного немає reason: спершу перевіряйте status.
  • Думати, що allSettled() робить код стійкішим сам собою. Він лише збирає звіт, а логіку повторів чи деградації ви пишете самі.
  • Забувати про HTTP помилки у fetch. fetch відхиляється лише на мережевій помилці, тому відповідь зі статусом 500 потрапить у fulfilled, і res.ok треба перевіряти окремо.
  • Брати allSettled() там, де потрібен fail-fast. Якщо перший збій робить решту роботи безглуздою, Promise.all() завершиться швидше і заощадить ресурси.

Коротка відповідь

Для співбесіди
Premium

Коротка відповідь допоможе вам впевнено відповідати на цю тему під час співбесіди.