What are the states of a Promise?
By FrontendPro Editorial Team Updated 9/26/2026
Answer
A promise is always in exactly one of three states:
- pending — the starting state; the operation has not finished.
- fulfilled — it finished successfully and carries a value.
- rejected — it failed and carries a reason, usually an
Error.
const p = new Promise((resolve, reject) => {
setTimeout(() => resolve("done"), 1000);
});
// pending now, fulfilled a second later
Transitions happen once and cannot be undone
A promise moves from pending to either fulfilled or rejected, and then it is settled — frozen for good. Calling resolve twice, or calling reject after resolve, has no effect; the first call wins and the rest are silently ignored. This is what makes promises safe to pass around: whoever receives one cannot have the result changed underneath them.
"Settled" is not a fourth state, just a word meaning "fulfilled or rejected". You will also see "resolved", which is subtly different — a promise can be resolved to another promise and still be pending until that one settles.
Reading the state
You cannot inspect it synchronously; that is deliberate. You attach handlers instead, and they run asynchronously as microtasks even if the promise already settled:
p.then(onFulfilled, onRejected);
p.catch(onRejected);
p.finally(cleanup); // runs either way, receives no value
await gives the fulfilled value or throws the rejection reason.
The practical consequence
A rejected promise with no rejection handler produces an unhandled rejection, which in Node terminates the process by default. Always terminate a chain with .catch(), or wrap the await in try/catch. And note that fetch() only rejects on network failure — an HTTP 500 fulfils, so a promise being fulfilled does not by itself mean the request succeeded.
