Promises
A promise is a placeholder for a value that starts pending and settles exactly once, to fulfilled or rejected.
Loading visual…
Definition
A `Promise` represents the eventual result of an asynchronous operation. It starts in the pending state and settles exactly one time, either to fulfilled, meaning the operation succeeded and produced a value, or rejected, meaning the operation failed and produced a reason. Once a promise settles, its state and value are locked in forever: calling `.then()` on an already-fulfilled promise, or `.catch()` on an already-rejected one, still runs the handler, just as if the settlement had just happened. `.then(onFulfilled, onRejected)` registers callbacks for the two outcomes, `.catch(onRejected)` is shorthand for `.then(undefined, onRejected)`, and `.finally(onSettled)` runs regardless of which way the promise settled, without receiving the value or reason. Each of these methods returns a new promise, which is what makes chaining possible: whatever a handler returns becomes the fulfillment value of that new promise, and a thrown error inside a handler becomes its rejection reason. Handlers registered with `.then`, `.catch`, and `.finally` never run synchronously, even if the promise is already settled when you attach them; they are always scheduled as microtasks, which is why a `.then()` callback runs after all currently running synchronous code, but before any setTimeout callback.
Examples
const p = new Promise((resolve, reject) => {
const ok = Math.random() > 0.5;
if (ok) resolve("done");
else reject(new Error("failed"));
});
p.then((value) => console.log("fulfilled:", value))
.catch((err) => console.log("rejected:", err.message));The executor settles the promise once, to fulfilled or rejected. Only the matching handler runs, .then's callback for a resolve, .catch's callback for a reject, never both.
Promise.resolve(1)
.then((n) => n + 1)
.then((n) => n * 10)
.then((n) => console.log(n)); // 20Each .then returns a new promise fulfilled with whatever the callback returns, so the value flows through the chain from one handler to the next.
Where you see this
- Wrapping a fetch() call so callers can .then() the parsed response or .catch() a network failure.
- Chaining dependent asynchronous steps, like reading a file then parsing then validating, without nesting callbacks.
- Using .finally() to hide a loading spinner regardless of whether a request succeeded or failed.
- Combining several independent promises with Promise.all or Promise.allSettled.