Skip to main content

Різниця між resolve і reject

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)Завершує проміс успішно, передає значення valuefulfilled.then(value => ...)
reject(reason)Завершує проміс з помилкою, передає reasonrejected.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() після нього ловить.

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

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

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