Запропонувати правкуПокращити цю статтюДопрацюйте відповідь до «Як працює ланцюжок промісів?». Ваші зміни проходять модерацію перед публікацією.Потрібне підтвердженняКонтентЩо ви змінюєте🇺🇸EN🇺🇦UAПереглядЗаголовок (UA)Коротка відповідь (UA)**Ланцюжок промісів** - це послідовне виконання асинхронних дій, де результат одного `.then()` передається наступному. **Ключове:** кожен `.then()`, `.catch()` та `.finally()` повертає новий проміс, що дозволяє вибудувати лінійний потік обробки без "callback hell".Показується над повною відповіддю для швидкого нагадування.Відповідь (UA)Зображення## Що таке ланцюжок промісів **Ланцюжок промісів** - це послідовне виконання асинхронних дій, де **результат одного** `.then()` **передається наступному**. Кожен `.then()`, `.catch()` та `.finally()` **повертає новий проміс**, що дозволяє вибудувати лінійний потік обробки - без "callback hell". ## Приклад базового ланцюжка ```javascript new Promise((resolve) => { setTimeout(() => resolve(10), 1000); }) .then((num) => { console.log('1. Отримали:', num); return num * 2; }) .then((num) => { console.log('2. Помножили:', num); return num + 5; }) .then((result) => { console.log('3. Підсумок:', result); }); ``` Вивід: ```javascript 1. Отримали: 10 2. Помножили: 20 3. Підсумок: 25 ``` Кожен `.then()`: 1. отримує результат попереднього кроку, 2. повертає **новий проміс**, 3. передає його результат далі по ланцюжку. ## Як це працює під капотом 1. **Перший проміс** створюється і переходить у `pending`. Коли викликається `resolve(value)`, він стає `fulfilled`. 2. Перший `.then()` отримує `value`, і повертає **новий проміс**, який тепер очікує наступний результат. 3. Кожен `.then()` у ланцюжку **дочікується виконання попереднього**, навіть якщо всередині повертається новий проміс. ### Приклад з асинхронним кроком ```javascript Promise.resolve(1) .then((n) => { console.log('A:', n); return new Promise((resolve) => setTimeout(() => resolve(n + 1), 1000) ); }) .then((n) => { console.log('B:', n); return n * 3; }) .then((n) => console.log('C:', n)); ``` Вивід (через секунду): ```javascript A: 1 B: 2 C: 6 ``` Тут: - `.then()` "розпізнає", що йому повернули новий проміс, - чекає, поки він завершиться (`resolve`), - і тільки потім виконує наступний крок ланцюжка. ## Помилки в ланцюжку Якщо в будь-якому `.then()` станеться помилка (`throw` або `reject`), усі наступні `.then()` **пропускаються**, і керування переходить у **перший найближчий** `.catch()`. ```javascript Promise.resolve(10) .then((x) => x / 2) .then(() => { throw new Error('Помилка!'); }) .then(() => console.log('не виконається')) .catch((err) => console.error('Спіймали:', err.message)) .then(() => console.log('продовжуємо')); ``` Вивід: ```javascript Спіймали: Помилка! продовжуємо ``` ## Повернення значень і промісів у `.then()` | Що повертає `.then()` | Що станеться | |---|---| | **Звичайне значення** | Обгортається у `Promise.resolve(value)` | | **Проміс** | Ланцюжок чекає, поки він завершиться | | **Помилка (throw)** | Ланцюжок переходить у `rejected` | | **Нічого не повертає** | Передає `undefined` далі | ## Приклад комбінування ```javascript Promise.resolve('A') .then((v) => v + 'B') // поверне 'AB' .then((v) => Promise.resolve(v + 'C')) // чекає інший проміс .then((v) => v + 'D') .then(console.log); // ABDC ``` ## Можна використовувати `.catch()` у середині ланцюжка ```javascript Promise.reject('Помилка') .catch((err) => { console.log('Спіймали:', err); return 'Відновлено'; }) .then((v) => console.log('Далі:', v)); ``` Вивід: ```javascript Спіймали: Помилка Далі: Відновлено ``` `.catch()` теж повертає новий проміс, тому після обробки помилки ланцюжок продовжується. ## `.finally()` у ланцюжку `finally()` виконується **завжди**, незалежно від результату, і не змінює значення (якщо не кидає помилку): ```javascript Promise.resolve('OK') .finally(() => console.log('Очищення...')) .then(console.log); ``` Вивід: ```javascript Очищення... OK ``` ## Приклад повного ланцюжка з помилками ```javascript Promise.resolve(1) .then((x) => x + 1) .then(() => { throw new Error('Ой!'); }) .catch((e) => { console.log('Помилку спіймано:', e.message); return 5; }) .then((x) => console.log('Результат:', x)) .finally(() => console.log('Готово')); ``` Вивід: ```javascript Помилку спіймано: Ой! Результат: 5 Готово ``` ## Проста аналогія Уяви ланцюжок промісів як **конвеєр**. - Кожен `.then()` - це **станція**, де деталь обробляється; - Якщо щось пішло не так - `.catch()` виправляє помилку і повертає на конвеєр; - Наприкінці `.finally()` вимикає станки і підмітає підлогу. ## Підсумок | Особливість | Опис | |---|---| | **Кожен** `.then()` | Повертає новий проміс | | **Значення передаються далі** | Результат з `.then()` йде в наступний | | **Помилки** | Передаються далі до найближчого `.catch()` | | `.finally()` | Виконується в будь-якому разі | | **Ланцюжок** | Дозволяє писати асинхронний код лінійно і без вкладеності |Для рев’юераПримітка для модератора (необов’язково)Бачить лише модератор. Прискорює рев’ю.