Запропонувати правкуПокращити цю статтюДопрацюйте відповідь до «Promise.allSettled() у JavaScript». Ваші зміни проходять модерацію перед публікацією.Потрібне підтвердженняКонтентЩо ви змінюєте🇺🇸EN🇺🇦UAПереглядЗаголовок (UA)Коротка відповідь (UA)**`Promise.allSettled()` приймає масив (або інший ітерований об'єкт) промісів і повертає новий проміс, який завершується тоді, коли завершилися геть усі передані проміси, незалежно від того, успішно (`fulfilled`) чи з помилкою (`rejected`). Такий проміс завжди переходить у стан `fulfilled` і віддає масив об'єктів виду `{status, value}` або `{status, reason}`, тобто повний звіт по кожному елементу. На відміну від `Promise.all()`, він не «падає» на першій помилці.** ```javascript Promise.allSettled([Promise.resolve('OK'), Promise.reject('Помилка')]) .then(console.log); // [{ status: "fulfilled", value: "OK" }, { status: "rejected", reason: "Помилка" }] ``` **Ключове:** `all()` це «все або нічого», а `allSettled()` це «звіт про все»: беріть його, коли треба дочекатися всіх операцій і побачити, що саме зламалося.Показується над повною відповіддю для швидкого нагадування.Відповідь (UA)Зображення**`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()` завершиться швидше і заощадить ресурси.Для рев’юераПримітка для модератора (необов’язково)Бачить лише модератор. Прискорює рев’ю.