Skip to main content

Difference between resolve and reject

resolve(value) finishes a promise successfully and makes it fulfilled, while reject(reason) finishes it with an error and makes it rejected. Both take the promise out of pending into a final state, just into different result branches.

Theory

TL;DR

  • resolve(value) says "the operation succeeded" and passes the value on to .then().
  • reject(reason) says "the operation failed" and passes the reason to .catch().
  • Both move the promise from pending to settled, and after that the state cannot change.
  • Calling either of them again is ignored, with no error raised.
  • .finally() runs regardless of which one fired.
  • If you pass another promise into resolve(), the outer promise waits for it, which is promise unwrapping.

Quick example

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'));

A possible output:

text
then: Everything went fine finally

or

text
catch: Something went wrong finally

How they work

MethodWhat it doesPromise stateWhat it triggers
resolve(value)Finishes the promise successfully, passes value alongfulfilled.then(value => ...)
reject(reason)Finishes the promise with an error, passes reason alongrejected.catch(error => ...)

After one of them is called:

  • the promise locks itself (settled),
  • a repeated resolve or reject call is ignored.

A resolve example

javascript
const promise = new Promise((resolve) => { setTimeout(() => { resolve('Data received!'); }, 1000); }); promise.then(result => console.log(result));

After 1 second:

text
Data received!

The promise moved into the fulfilled state.

A reject example

javascript
const promise = new Promise((resolve, reject) => { setTimeout(() => { reject('Network error'); }, 1000); }); promise.catch(error => console.error(error));

After 1 second:

text
Network error

The promise moved into the rejected state.

The state changes only once

javascript
const promise = new Promise((resolve, reject) => { resolve('OK'); reject('Error'); // ignored }); promise.then(console.log).catch(console.error);

After the first call (resolve) the promise became fulfilled, so the second call (reject) has no effect at all.

resolve with another promise

If you pass another Promise into resolve(), the current promise waits for it to finish.

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

This is called promise unwrapping. reject() does not do this: a promise handed to it simply becomes the rejection reason, nothing unwraps it.

Handling the results

javascript
new Promise((resolve, reject) => { resolve('OK'); }).then(console.log); // OK new Promise((resolve, reject) => { reject('Error'); }).catch(console.error); // Error

A parcel delivery analogy:

resolve is the courier arriving with the parcel, everything worked. reject is the courier calling to say "address not found", something failed.

Summary table

MethodStateWhat it passesWhere it is handledAnalogy
resolve(value)fulfilledThe successful result.then()The parcel was delivered
reject(reason)rejectedThe error or refusal reason.catch()The courier could not deliver
After the callThe promise becomes settled and can no longer changeNothing.finally()The route is closed

Common mistakes

  • Calling resolve() and reject() next to each other and expecting both to fire. The first one wins, the second is silently ignored.
  • Passing a string into reject() instead of an Error. Prefer reject(new Error('Network error')), which gives you a stack trace and a proper message.
  • Thinking reject throws into the surrounding code. It only moves the promise into rejected, and without a .catch() that becomes an unhandled rejection.
  • Assuming the executor stops after resolve(). It is an ordinary function call: the lines below still run, they just cannot change anything, so write return resolve(value).
  • Forgetting that resolve(anotherPromise) waits. Such a promise does not become fulfilled immediately, it ties itself to the promise you passed in.
  • Putting error handling only in the second argument of .then(). .then(onOk, onErr) does not catch an error thrown inside onOk, while a trailing .catch() does.

Short Answer

Interview ready
Premium

A concise answer to help you respond confidently on this topic during an interview.