Запропонувати правкуПокращити цю статтюДопрацюйте відповідь до «Promise». Ваші зміни проходять модерацію перед публікацією.Потрібне підтвердженняКонтентЩо ви змінюєте🇺🇸EN🇺🇦UAПереглядЗаголовок (UA)Коротка відповідь (UA)**Promise - це спеціальний об'єкт, який представляє результат асинхронної операції, що завершиться пізніше: успішно (`fulfilled`) або з помилкою (`rejected`).** Поки операція триває, Promise перебуває у стані `pending`; `resolve(value)` переводить його у `fulfilled`, `reject(error)` - у `rejected`. На результат підписуються через `.then()`, помилку ловлять через `.catch()`, а `.finally()` спрацьовує в будь-якому разі; кожен із цих методів повертає новий Promise, тому дії шикуються в пласкі ланцюжки замість callback hell. ```javascript fetchData() .then((data) => console.log(data)) .catch((err) => console.error(err)); ``` **Ключове:** Promise - це «обіцянка» дати результат у майбутньому; саме на ньому побудований синтаксис `async/await`.Показується над повною відповіддю для швидкого нагадування.Відповідь (UA)Зображення**Promise - це спеціальний об'єкт у JavaScript, який представляє результат асинхронної операції, що може завершитися пізніше, успішно або з помилкою.** Простіше кажучи, Promise - це «обіцянка» дати результат у майбутньому: зараз відповіді немає, але вона буде, коли операція завершиться. ## Теорія ### TL;DR - Promise представляє майбутній результат асинхронної операції. - Стани: `pending`, далі або `fulfilled`, або `rejected`; перехід відбувається лише один раз. - `resolve(value)` переводить у `fulfilled`, `reject(error)` - у `rejected`. - Обробка результату: `.then()`, `.catch()`, `.finally()`; кожен із них повертає новий Promise. - Комбінатори: `Promise.all()`, `Promise.allSettled()`, `Promise.race()`. - `async/await` - це синтаксичний цукор над Promise, а не окремий механізм. ### Швидкий приклад ```javascript function fetchData() { return new Promise((resolve) => { setTimeout(() => { resolve('Дані отримано!'); }, 2000); }); } fetchData().then((data) => console.log(data)); ``` `fetchData()` повертає Promise: через 2 секунди він резолвиться, і `then()` отримує результат. ### Три стани Promise | Стан | Опис | Приклад | | --- | --- | --- | | **pending** | очікування, операція ще не завершена | запит у процесі | | **fulfilled** | виконано успішно, є результат | дані отримано | | **rejected** | відхилено, сталася помилка | сервер повернув 404 | ### Створення Promise і обробка результату Promise можна створити вручну: ```javascript const promise = new Promise((resolve, reject) => { const success = Math.random() > 0.5; if (success) { resolve('Успіх!'); } else { reject('Помилка!'); } }); ``` - `resolve(value)` переводить Promise у стан **fulfilled**; - `reject(error)` переводить його у стан **rejected**. Результат обробляють ланцюжком методів: ```javascript promise .then((result) => { console.log('Результат:', result); }) .catch((error) => { console.error('Помилка:', error); }) .finally(() => { console.log('Виконується завжди'); }); ``` | Метод | Коли викликається | Що повертає | | --- | --- | --- | | `.then()` | при успішному виконанні (`resolve`) | новий Promise | | `.catch()` | при помилці (`reject`) | новий Promise | | `.finally()` | у будь-якому разі (успіх або помилка) | новий Promise | Приклад із помилкою: ```javascript function fetchUser() { return new Promise((_, reject) => { setTimeout(() => reject('Користувача не знайдено'), 1000); }); } fetchUser() .then(user => console.log(user)) .catch(err => console.error(err)); ``` Вивід: ```text Користувача не знайдено ``` ### Ланцюжки Promise (promise chaining) Кожен `.then()` повертає новий Promise, тому асинхронні дії можна вишиковувати в ланцюжок: ```javascript getUser() .then(user => getPosts(user.id)) .then(posts => getComments(posts[0].id)) .then(comments => console.log(comments)) .catch(err => console.error('Помилка:', err)); ``` Перевага: немає вкладеності, код читається згори вниз, на відміну від callback hell. Для вже готового значення є скорочена форма: ```javascript Promise.resolve('OK').then(console.log); // "OK" Promise.reject('Помилка').catch(console.error); // "Помилка" ``` ### Паралельні Promise #### `Promise.all()` чекає, поки виконаються всі ```javascript Promise.all([ fetch('/user'), fetch('/posts'), ]).then(([userRes, postRes]) => { console.log('Обидві відповіді отримано'); }); ``` Якщо хоча б один Promise завершиться з помилкою, увесь `all()` буде `rejected`. #### `Promise.allSettled()` чекає всі, незалежно від помилок ```javascript Promise.allSettled([ fetch('/user'), fetch('/wrong-url'), ]).then(console.log); ``` Результат: ```javascript [ { status: "fulfilled", value: Response }, { status: "rejected", reason: TypeError } ] ``` #### `Promise.race()` повертає перший, що завершився ```javascript Promise.race([ fetch('/slow'), fetch('/fast'), ]).then(console.log); ``` ### Promise і async/await Promise - це основа, на якій побудований синтаксис `async/await`: ```javascript async function main() { try { const user = await getUser(); const posts = await getPosts(user.id); console.log(posts); } catch (err) { console.error(err); } } ``` Тут `await` просто чекає на Promise, але робить код лінійним і зрозумілим. Проста аналогія: > Promise схожий на доставку піци. Ви робите замовлення, і Promise створюється у стані `pending`. Кур'єр везе замовлення, операція виконується. Кур'єр приїхав, Promise переходить у `resolve`. Кур'єр загубився, Promise переходить у `reject`. Ви можете «підписатися» на результат через `then` і обробити помилки через `catch`. ### Підсумок | Термін | Опис | | --- | --- | | **Promise** | Об'єкт, що представляє майбутній результат асинхронної операції | | **Стани** | `pending`, далі `fulfilled` або `rejected` | | **Методи** | `.then()`, `.catch()`, `.finally()` | | **Головна перевага** | Спрощує роботу з асинхронністю, рятує від callback hell | | **Сучасний синтаксис** | `async/await` побудований на Promise | ### Типові помилки - Думати, що Promise можна «перерезолвити»: після першого `resolve` або `reject` стан фіксується назавжди, наступні виклики ігноруються. - Вважати, що Promise виконується ліниво. Функція-виконавець стартує одразу в момент `new Promise(...)`, ще до будь-якого `.then()`. - Забути `return` усередині `.then()`, через що наступна ланка отримує `undefined` замість даних. - Ставити `.catch()` не в кінці ланцюжка: тоді помилки з наступних `.then()` залишаться без обробки. - Брати `Promise.all()` там, де потрібен `Promise.allSettled()`: одна помилка відкидає весь результат, хоча інші запити вже виконалися успішно. - Плутати `Promise.race()` з `Promise.any()`: `race` повертає перший завершений результат, навіть якщо це помилка, а `any` чекає на перший успішний. - Загортати в `new Promise` функцію, яка вже повертає Promise: це зайвий рівень і джерело загублених помилок.Для рев’юераПримітка для модератора (необов’язково)Бачить лише модератор. Прискорює рев’ю.