Запропонувати правкуПокращити цю статтюДопрацюйте відповідь до «Різниця між resolve і reject». Ваші зміни проходять модерацію перед публікацією.Потрібне підтвердженняКонтентЩо ви змінюєте🇺🇸EN🇺🇦UAПереглядЗаголовок (UA)Коротка відповідь (UA)**`resolve(value)` повідомляє, що операція завершилася успішно, і переводить проміс у стан `fulfilled`, а `reject(reason)` повідомляє про помилку і переводить його у `rejected`.** Обидва переводять проміс із `pending` у кінцевий стан `settled`, але в різні «гілки»: значення з `resolve` потрапляє в `.then()`, причина з `reject` потрапляє в `.catch()`, а `.finally()` спрацьовує в обох випадках. Після першого виклику проміс фіксується, і повторний виклик `resolve` чи `reject` просто ігнорується. ```javascript new Promise((resolve) => resolve('OK')).then(console.log); // OK new Promise((resolve, reject) => reject('Error')).catch(console.error); // Error ``` **Ключове:** `resolve` це гілка успіху для `.then()`, `reject` це гілка помилки для `.catch()`, і спрацьовує лише той, хто був першим.Показується над повною відповіддю для швидкого нагадування.Відповідь (UA)Зображення**`resolve(value)` завершує проміс успішно і робить його `fulfilled`, а `reject(reason)` завершує його з помилкою і робить `rejected`.** Обидві функції виводять проміс зі стану `pending` у кінцевий стан, просто в різні гілки результату. ## Теорія ### TL;DR - `resolve(value)` каже «операція вдалася» і передає значення далі в `.then()`. - `reject(reason)` каже «операція провалилася» і передає причину в `.catch()`. - Обидва переводять проміс із `pending` у `settled`, змінити стан після цього неможливо. - Повторний виклик будь-якого з них ігнорується без помилки. - `.finally()` виконується незалежно від того, який із них спрацював. - Якщо в `resolve()` передати інший проміс, зовнішній проміс дочекається його, це promise unwrapping. ### Швидкий приклад ```javascript const promise = new Promise((resolve, reject) => { const success = Math.random() > 0.5; if (success) { resolve('Everything went fine'); } else { reject('Something went wrong'); } }); promise .then(result => console.log('then:', result)) .catch(error => console.log('catch:', error)) .finally(() => console.log('finally')); ``` Можливий вивід: ```text then: Everything went fine finally ``` або ```text catch: Something went wrong finally ``` ### Як вони працюють | Метод | Що робить | Стан промісу | Що викличе | | --- | --- | --- | --- | | `resolve(value)` | Завершує проміс успішно, передає значення `value` | **fulfilled** | `.then(value => ...)` | | `reject(reason)` | Завершує проміс з помилкою, передає `reason` | **rejected** | `.catch(error => ...)` | Після виклику одного з них: - проміс «фіксується» (settled), - повторний виклик `resolve` або `reject` буде проігноровано. ### Приклад з resolve ```javascript const promise = new Promise((resolve) => { setTimeout(() => { resolve('Data received!'); }, 1000); }); promise.then(result => console.log(result)); ``` Через 1 секунду: ```text Data received! ``` Проміс перейшов у стан **fulfilled**. ### Приклад з reject ```javascript const promise = new Promise((resolve, reject) => { setTimeout(() => { reject('Network error'); }, 1000); }); promise.catch(error => console.error(error)); ``` Через 1 секунду: ```text Network error ``` Проміс перейшов у стан **rejected**. ### Стан змінюється лише один раз ```javascript const promise = new Promise((resolve, reject) => { resolve('OK'); reject('Error'); // ignored }); promise.then(console.log).catch(console.error); ``` Після першого виклику (`resolve`) проміс став **fulfilled**, тож другий виклик (`reject`) не має жодного ефекту. ### resolve з іншим промісом Якщо у `resolve()` передати **інший Promise**, поточний проміс **чекатиме** на його завершення. ```javascript const inner = new Promise((resolve) => setTimeout(() => resolve('Inner result'), 1000)); const outer = new Promise((resolve) => resolve(inner)); outer.then(console.log); // prints "Inner result" after 1 second ``` Це називається **promise unwrapping**, тобто «розгортання» промісів. `reject()` так не вміє: переданий у нього проміс стане звичайною причиною відмови, його ніхто не розгортатиме. ### Обробка результатів ```javascript new Promise((resolve, reject) => { resolve('OK'); }).then(console.log); // OK new Promise((resolve, reject) => { reject('Error'); }).catch(console.error); // Error ``` Аналогія з доставкою посилки: > `resolve` це кур'єр привіз посилку, все успішно. > `reject` це кур'єр зателефонував і сказав «адресу не знайдено», сталася помилка. ### Підсумкова таблиця | Метод | Стан | Що передає | Де обробляється | Аналогія | | --- | --- | --- | --- | --- | | `resolve(value)` | fulfilled | Успішний результат | `.then()` | Посилку доставлено | | `reject(reason)` | rejected | Помилку або причину відмови | `.catch()` | Кур'єр не зміг доставити | | Після виклику | Проміс стає `settled`, змінити його вже не можна | Нічого | `.finally()` | Маршрут закрито | ### Типові помилки - **Викликати `resolve()` і `reject()` поруч і чекати, що спрацюють обидва.** Виграє перший, другий мовчки ігнорується. - **Передавати в `reject()` рядок замість `Error`.** Краще `reject(new Error('Network error'))`: тоді є стек виклику і нормальне повідомлення. - **Думати, що `reject` кидає виняток у зовнішній код.** Він лише переводить проміс у `rejected`, а без `.catch()` це стає unhandled rejection. - **Вважати, що після `resolve()` код у виконавці зупиняється.** Це звичайний виклик функції: рядки нижче виконаються, просто вже нічого не змінять, тому пишіть `return resolve(value)`. - **Забувати, що `resolve(anotherPromise)` чекає.** Такий проміс не стане `fulfilled` одразу, він пов'яже себе з переданим промісом. - **Класти обробку помилок тільки в другий аргумент `.then()`.** `.then(onOk, onErr)` не ловить помилку, кинуту в самому `onOk`, а `.catch()` після нього ловить.Для рев’юераПримітка для модератора (необов’язково)Бачить лише модератор. Прискорює рев’ю.