Promises
Create and chain promises, handle errors, and combine them with all, allSettled, race and any.
A promise is an object representing a value that isn't available yet — the result of a network request, a timer or a file read. Instead of passing a callback into a function, the function returns a promise, and you attach handlers to it. Promises fix the problems of callback hell: they chain, they have one consistent way to handle errors, and they can be combined.
The life of a promise#
A promise is always in one of three states:
- pending — the work is in progress
- fulfilled — it finished successfully, with a value
- rejected — it failed, with a reason (usually an
Error)
Once fulfilled or rejected, a promise is settled and never changes again.
Consuming promises: then, catch, finally#
Most of the time you use promises that APIs give you. fetch, for example, returns a promise:
.then(onFulfilled)runs when the promise fulfils, receiving its value..catch(onRejected)runs if anything earlier in the chain rejected or threw..finally(fn)runs either way — ideal for hiding a loading spinner.
Every one of these returns a new promise, which is what makes chaining possible.
Creating promises#
Wrap a callback-based or timer-based operation with new Promise:
The function you pass to new Promise is the executor. It runs immediately and receives two functions: call resolve(value) on success or reject(error) on failure. Only the first call counts.
Shortcuts for already-settled promises:
Chaining#
Whatever a .then callback returns becomes the value for the next .then. If it returns a promise, the chain waits for it:
Compare this flat chain with the nested pyramid from the callbacks lesson.
The #1 promise bug is forgetting to
returninside.then. Without it, the next step runs immediately withundefined, and errors from the inner promise aren't caught by your.catch.
Error handling#
A rejection — or an error thrown inside any handler — skips the following .thens and jumps to the next .catch:
A .catch can recover (by returning a value) or re-throw to pass the error on. Put one .catch at the end of each chain.
Unhandled rejections
If a promise rejects and nobody catches it, you get an "unhandled promise rejection" warning in the browser console. In Node.js, the process crashes by default. Always end chains with .catch (or use try/catch with await).
Combining promises#
Promise.all — run in parallel, wait for all
Results keep the input order, regardless of which finished first. If any promise rejects, Promise.all rejects immediately with that error.
Promise.allSettled — wait for all, never rejects
Use it when partial success is fine — e.g. loading independent widgets on a dashboard.
Promise.race — first to settle wins
(For fetch, there's a built-in way to time out with AbortSignal.timeout — see fetch, APIs & JSON.)
Promise.any — first to fulfil wins
It rejects only if all fail, with an AggregateError containing every reason.
Promise.withResolvers#
Sometimes you need to resolve a promise from outside the executor — e.g. waiting for a user to click a button in a dialog:
Promise callbacks are always asynchronous#
Even if a promise is already resolved, .then callbacks run later, as microtasks (see The event loop):
This consistency avoids the "sometimes sync, sometimes async" bugs of callback APIs.
Common mistakes#
- Forgetting to
returna promise inside.then. - Nesting
.thens inside.thens (recreating callback hell) — return and chain instead. - Missing a final
.catch, causing unhandled rejections. - Wrapping a function that already returns a promise in
new Promise(the "explicit construction anti-pattern"). Just return the existing promise. - Running independent requests one after another instead of in parallel with
Promise.all.
What's next#
Promise chains are much better than callbacks, but there's an even more readable syntax built on top of them: async and await.
Check your understanding
Quick quiz
1.What are the three states of a promise?
2.What does
Promise.all([p1, p2, p3])do ifp2rejects?3.Inside a
.thencallback, what happens if you return another promise?
Finished reading?
Mark this lesson complete to track your progress.