References

Beginner-friendly references for web development, with live, editable examples.

The JavaScript Promise object

Object JavaScript All modern browsers Updated
Quick answer

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

Live 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 around await.
  • 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?
An object representing the eventual result of an asynchronous operation. It's pending until it either fulfills with a value or rejects with an error.
What are the three states of a Promise?
Pending (in progress), fulfilled (succeeded), and rejected (failed). Once it settles to fulfilled or rejected, it can't change.
What is the difference between promises and async/await?
async/await is syntactic sugar over promises that lets you write async code in a sequential style. Under the hood, async functions still return promises.
How do I run multiple promises at once?
Use 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.