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
pendingtosettled, 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
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:
then: Everything went fine
finallyor
catch: Something went wrong
finallyHow they work
| Method | What it does | Promise state | What it triggers |
|---|---|---|---|
resolve(value) | Finishes the promise successfully, passes value along | fulfilled | .then(value => ...) |
reject(reason) | Finishes the promise with an error, passes reason along | rejected | .catch(error => ...) |
After one of them is called:
- the promise locks itself (settled),
- a repeated
resolveorrejectcall is ignored.
A resolve example
const promise = new Promise((resolve) => {
setTimeout(() => {
resolve('Data received!');
}, 1000);
});
promise.then(result => console.log(result));After 1 second:
Data received!The promise moved into the fulfilled state.
A reject example
const promise = new Promise((resolve, reject) => {
setTimeout(() => {
reject('Network error');
}, 1000);
});
promise.catch(error => console.error(error));After 1 second:
Network errorThe promise moved into the rejected state.
The state changes only once
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.
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 secondThis 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
new Promise((resolve, reject) => {
resolve('OK');
}).then(console.log); // OK
new Promise((resolve, reject) => {
reject('Error');
}).catch(console.error); // ErrorA parcel delivery analogy:
resolveis the courier arriving with the parcel, everything worked.rejectis the courier calling to say "address not found", something failed.
Summary table
| Method | State | What it passes | Where it is handled | Analogy |
|---|---|---|---|---|
resolve(value) | fulfilled | The successful result | .then() | The parcel was delivered |
reject(reason) | rejected | The error or refusal reason | .catch() | The courier could not deliver |
| After the call | The promise becomes settled and can no longer change | Nothing | .finally() | The route is closed |
Common mistakes
- Calling
resolve()andreject()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 anError. Preferreject(new Error('Network error')), which gives you a stack trace and a proper message. - Thinking
rejectthrows into the surrounding code. It only moves the promise intorejected, 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 writereturn resolve(value). - Forgetting that
resolve(anotherPromise)waits. Such a promise does not becomefulfilledimmediately, 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 insideonOk, while a trailing.catch()does.
Short Answer
Interview readyA concise answer to help you respond confidently on this topic during an interview.