"Remember callbacks? Well JavaScript made them a promise — and this time it kept it."
Callbacks came first, but they had a problem — "Callback Hell" — when you nest too many callbacks it becomes a messy pyramid of doom. Promises were created to solve exactly that.
Promise
A promise is an object that might produce a value at some point in the future.
A Promise is in one of these states:
- pending: initial state, neither fulfilled nor rejected.
- fulfilled: the operation was completed successfully.
- rejected: the operation failed.
let myPromise = new Promise(function(resolve, reject) {
// Code that may take some time
resolve(value); // when successful
reject(value); // when error
});
While a Promise is in the pending state, it's said to be unresolved. When it finishes its work, it becomes resolved — whether it was fulfilled or rejected.
Handling a Promise's Outcome
Once a promise resolves, you need a way to react to it. That's where these three methods come in.
.then()
Called when a promise is fulfilled. Whatever you passed into resolve() lands here.
myPromise.then(function(value) {
console.log("Got it:", value);
});
💡 Think of it like: "When you're done, do this with the result."
.catch()
Called when a promise is rejected. Whatever you passed into reject() lands here.
myPromise.catch(function(error) {
console.log("Something went wrong:", error);
});
💡 Think of it like: "If something breaks, handle it here."
.finally()
Runs no matter what — fulfilled or rejected. Good for cleanup work (like hiding a loading spinner).
myPromise.finally(function() {
console.log("Done — one way or another.");
});
💡 Think of it like: "Whether it worked or not, do this last thing."
And since these methods return a promise themselves, you can chain them:
myPromise
.then(value => console.log("Success:", value))
.catch(error => console.log("Error:", error))
.finally(() => console.log("All done!"));
Promise Static Methods
These live on the Promise object itself and deal with multiple promises at once.
Promise.all()
Takes an array of promises and waits for all of them to fulfill. If even one rejects, the whole thing rejects.
Promise.all([promise1, promise2, promise3])
.then(values => console.log(values)) // [result1, result2, result3]
.catch(error => console.log("One failed:", error));
💡 Think of it like: "Everyone has to show up, or we're not starting."
Promise.allSettled()
Like Promise.all(), but it never rejects — it waits for every promise to finish (fulfilled or rejected) and gives you a report on each one.
Promise.allSettled([promise1, promise2])
.then(results => {
results.forEach(result => console.log(result.status, result.value ?? result.reason));
});
💡 Think of it like: "Tell me how everyone did, good or bad."
Promise.race()
Resolves or rejects as soon as the first promise settles — whoever finishes first wins.
Promise.race([promise1, promise2])
.then(value => console.log("First one done:", value));
💡 Think of it like: "First to cross the finish line, wins."
Promise.any()
Resolves as soon as any one promise fulfills. Only rejects if all of them reject.
Promise.any([promise1, promise2])
.then(value => console.log("First success:", value))
.catch(() => console.log("All of them failed."));
💡 Think of it like: "I just need one person to show up."
Quick Comparison
| Method | Resolves when | Rejects when |
|---|---|---|
Promise.all |
All fulfill | Any one rejects |
Promise.allSettled |
All settle (either way) | Never |
Promise.race |
First one settles | First one rejects |
Promise.any |
First one fulfills | All reject |
Promises won't fix all your async problems — but unlike callbacks, at least they'll let you know when they've failed you.
Happy coding 😊!!!
Top comments (0)