Promises: Pending, Fulfilled & Rejected
Quick Overview
A promise settles once and keeps its result, so a `.then()` attached afterwards still fires. `.catch()` handles a rejection from anywhere earlier in the chain, which is why one at the end usually suffices.
Deep Dive
1. Future Value Guarantees
A Promise is a built-in object representing the eventual completion or failure of an asynchronous operation.
2. Why It Matters
Promises replace nested callback spaghetti with clean, chainable asynchronous pipelines that propagate errors safely down the chain.
3. The 3 Promise States
pending: Initial state; operation is still in progress.fulfilled: Operation completed successfully (resolve(value)).rejected: Operation failed (reject(error)).
const fetchUserData = new Promise((resolve, reject) => {
const success = true;
if (success) {
resolve({ id: 101, name: "Alex" });
} else {
reject("Network connection failed.");
}
});
fetchUserData
.then((user) => {
console.log("Loaded:", user.name);
return user.id;
})
.then((id) => console.log("User ID:", id))
.catch((err) => console.error("Error:", err));
4. Promise Combinators
Promise.all([p1, p2]): Fails fast if ANY promise rejects. Resolves when ALL pass.Promise.allSettled([p1, p2]): Waits for all promises to finish regardless of success or failure.
5. Common Mistakes
- Unhandled Promise Rejections: Always attach a
.catch()handler or usetry...catchwithasync/await. Unhandled Promise rejections emit runtime warnings and can crash Node.js servers! - Nested Promises (Pyramid of Doom): Returning a promise inside a
.then()flattens the chain automatically. Do not nest.then()calls inside.then().
6. Try It Yourself
Write it yourself. The tests below run against your code.
Check Online Status Result
Examples
7. Next Steps
Promises encapsulate async state. Next, let's make Promises look synchronous with async/await!
Next Up in JavaScript Engine & Core Language
Data Types in JavaScript: Primitives vs. Objects
Primitives copy by value and objects copy by reference, so `b = a` duplicates a number but shares an object. That single distinction explains most surprise mutations in a codebase.
Variables: const, let & var (The Box Metaphor)
`const` prevents reassignment, not mutation: a `const` object's properties can still be changed. `let` is scoped to its block, while `var` is function-scoped and leaks out of loops.
Strings & Template Literals `${}`
Only backticks interpolate: `${user}` reads the variable, while the identical text in quotes prints literally. Strings are immutable, so every method returns a new one rather than editing in place.