Skip to content
Happy Programming Guide
Start learning
JavaScript

JavaScript Async and Await Explained

Why some code finishes later, what a promise is, and how async/await lets you write waiting code that still reads top to bottom.

Some things in JavaScript take time — fetching data, reading a file, waiting for a timer. Rather than freezing the page, JavaScript starts them and carries on. Your code has to be written to cope with that.

The problem, shown in three lines#

JavaScript
console.log("first");

setTimeout(() => console.log("second"), 1000);

console.log("third");

// prints: first, third, second

JavaScript did not wait. It started the timer, moved on, and came back a second later. Everything about async programming follows from this.

What a promise is#

A promise is an object that stands for a result you do not have yet. It is in one of three states: pending, fulfilled, or rejected.

JavaScript
const promise = fetch("/api/users");

console.log(promise);    // Promise { <pending> } — not the data

You cannot use the value directly. You have to say what should happen once it arrives.

The old way: .then()#

JavaScript
fetch("/api/users")
  .then(response => response.json())
  .then(users => console.log(users))
  .catch(error => console.log("Something went wrong:", error));

This works, and you will see plenty of it. It gets awkward once steps depend on each other.

The readable way: async and await#

JavaScript
async function showUsers() {
  try {
    const response = await fetch("/api/users");
    const users = await response.json();
    console.log(users);
  } catch (error) {
    console.log("Something went wrong:", error);
  }
}

showUsers();

Two rules:

  • await pauses that function until the promise settles
  • You can only use await inside a function marked async

The code now reads top to bottom, like ordinary code, while still not blocking the page.

An async function always returns a promise#

JavaScript
async function getName() {
  return "Ada";
}

console.log(getName());          // Promise { 'Ada' }
console.log(await getName());    // Ada

This is why you cannot call an async function and use its result directly — you have to await it too, or chain .then().

Waiting for several things at once#

JavaScript
// Slow — one after another
const users = await fetch("/api/users");
const posts = await fetch("/api/posts");

// Fast — both start immediately
const [users2, posts2] = await Promise.all([
  fetch("/api/users"),
  fetch("/api/posts"),
]);

Use Promise.all when the requests do not depend on each other. If one fails, the whole thing rejects — Promise.allSettled gives you every result regardless.

Handling errors#

JavaScript
async function loadData() {
  try {
    const response = await fetch("/api/data");
    if (!response.ok) {
      throw new Error(`Server said ${response.status}`);
    }
    return await response.json();
  } catch (error) {
    console.error("Could not load data:", error.message);
    return null;
  }
}

Note that fetch does not throw on a 404 or 500. You have to check response.ok yourself — a genuine trap. See the Fetch API guide.

Questions people ask#

Does await block the whole page?

No. It pauses only the async function it is in. The rest of the page keeps responding, which is the entire point.

Can I use await at the top level of a file?

In modern JavaScript modules, yes. In a plain script, wrap it in an async function.

What is a callback, and how does it relate?

A callback is a function passed in to be run later. Promises were introduced because deeply nested callbacks became hard to read; async/await made promises easier again.

Why is my loop with await so slow?

Because for ... of with await runs one request at a time. Build an array of promises and pass it to Promise.all to run them together.

Where to go next#

Next lessonJavaScript Fetch API explained

Keep reading

Keep going — pick your next guide

The fastest way to improve is to read one guide, then build the thing it describes. Start with the basics, or jump straight to a project.

Ask a question or share what worked

Your email address will not be published. Required fields are marked *