What is a Promise?
By FrontendPro Editorial Team Updated 9/26/2026
Answer
A promise is an object representing a value that is not available yet. Instead of passing a callback in and waiting to be called, you receive an object and attach handlers to it.
const p = fetch("/api/user"); // a Promise, not the response
p.then((res) => res.json())
.then((user) => console.log(user.name))
.catch((err) => console.error(err));
Chaining is the point
Each .then returns a new promise, so steps compose in a flat line instead of nesting. Returning a promise from inside a handler waits for it before continuing:
loadUser(id)
.then((user) => loadPosts(user.id)) // returned promise is awaited
.then((posts) => render(posts))
.catch(handleAnyFailureAbove);
One .catch at the end covers every step above it, which is the main improvement over callbacks — errors travel along the chain rather than needing a check at each level.
Creating one
Only when wrapping something that is not already promise-based:
const wait = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
Wrapping a function that already returns a promise in new Promise is a common anti-pattern — it adds nothing and usually loses error handling.
async/await is the same thing
await unwraps a promise and async wraps the return value in one. It is syntax over the same objects, so the two mix freely:
async function load() {
const res = await fetch("/api/user"); // same promise as above
return res.json();
}
Two things to remember
Handlers always run asynchronously as microtasks, even if the promise already settled — so code after .then(...) runs first.
And a promise starts executing the moment it is created, not when you await it. const p = load() has already begun the work; awaiting only decides when you look at the result.
