The JavaScript Promise object
A Promise represents a value that isn't ready yet — the eventual result of an asynchronous operation like a fetch(). It's in one of three states: pending, fulfilled or rejected. Consume it with .then()/.catch(), or more cleanly with async/await.
Overview
A Promise is a placeholder for a value that will arrive later — the result of something asynchronous, like a network request, a timer, or reading a file. Rather than blocking while it waits, your code gets a promise immediately and attaches handlers that run when the result is ready. Most async APIs, including fetch(), return promises.
A promise is always in one of three states: pending (still working), fulfilled (succeeded, with a value), or rejected (failed, with an error). You react to the outcome with .then() for success and .catch() for failure, chaining them for sequences of async steps. But chains get noisy, which is why the modern style is async/await — syntactic sugar over promises that reads like ordinary top-to-bottom code, with try...catch for errors.
Several static helpers coordinate multiple promises. Promise.all([...]) waits for all of them and fails fast if any reject — ideal for running independent requests in parallel. Promise.allSettled([...]) waits for all and reports each outcome. Promise.race([...]) settles as soon as the first one does. And Promise.resolve()/Promise.reject() create already-settled promises, handy in tests and adapters.
Syntax
// consume with then / catch
fetch(url)
.then(res => res.json())
.then(data => console.log(data))
.catch(err => console.error(err));
// or with async / await (preferred)
const data = await (await fetch(url)).json();
// run several in parallel
const [a, b] = await Promise.all([fetchA(), fetchB()]);
Example
<pre id="out" style="font:15px ui-monospace,monospace"></pre>
<script>
// a promise that resolves after a delay
const wait = (val, ms) => new Promise(resolve => setTimeout(() => resolve(val), ms));
const out = document.getElementById('out');
out.textContent = 'Pending...';
Promise.all([wait('A', 500), wait('B', 800)])
.then(results => { out.textContent = 'Fulfilled: ' + results.join(', '); })
.catch(err => { out.textContent = 'Rejected: ' + err; });
</script>
Best practices
- Prefer async/await over long
.then()chains for readability. - Always handle rejections — with
.catch()or try...catch aroundawait. - Run independent async work in parallel with
Promise.all([...])instead of awaiting one at a time. - Use
Promise.allSettled()when you want every result even if some fail.
Frequently asked questions
What is a Promise in JavaScript?
What are the three states of a Promise?
What is the difference between promises and async/await?
How do I run multiple promises at once?
Promise.all([p1, p2]) to run them in parallel and wait for all to finish, or Promise.allSettled() to get every outcome even if some reject.