Photo by Eric Er on Unsplash

On this page

This chapter follows Callbacks and timers.

A Promise is an object representing a single value available in the future. Producers call resolve or reject; consumers attach reactions with .then, .catch, and .finally.

States

A promise is pending, then becomes fulfilled (with a value) or rejected (with a reason). Settled promises ignore later resolve/reject calls.

const p = new Promise((resolve, reject) => {
setTimeout(() => resolve("done"), 100);
});
p.then((value) => console.log(value)); // "done"

Chaining

.then returns a new promise, which enables pipelines:

fetch("/api/user")
.then((res) => {
if (!res.ok) throw new Error(String(res.status));
return res.json();
})
.then((user) => console.log(user.name))
.catch((err) => console.error(err));

Throwing inside then rejects the returned promise. Returning a value fulfills it; returning another promise adopts that promise’s outcome.

Static combinators

Method Behavior
Promise.all(iterable) Fulfills with an array of results; first reject fails the whole
Promise.allSettled(iterable) Waits for all; never short-circuits on reject
Promise.race(iterable) Settles with the first fulfilled or rejected
Promise.any(iterable) Fulfills with first success; AggregateError if all fail
Promise.resolve(x) / Promise.reject(r) Wrap values or reasons
const [user, posts] = await Promise.all([
fetch("/api/user").then((r) => r.json()),
fetch("/api/posts").then((r) => r.json()),
]);

Microtasks and unhandled rejections

Promise reactions run as microtasks—before the next timer or I/O callback. A rejected promise with no .catch may surface as an unhandled rejection in Node or the browser console.

Always end chains with .catch or try/catch around await.

Promise versus Observable

Promises model one result. Observables model many values and optional unsubscribe. The series closes with a comparison chapter.

Continue with Async/await in JavaScript.

Search articles

Type a word to search published articles.

Open the search page