How to Use Async/Await in JavaScript

Use async and await when code depends on asynchronous results like API calls, database reads, timers, or file operations. This makes async logic read much closer to normal top-to-bottom code.

What you’ll build or solve

You’ll learn how to use async/await in JavaScript to wait for promises cleanly. You’ll also know how to handle errors and run async code in the right places.

When this approach works best

This approach is the right choice when one async step depends on the result of another.

Common real-world scenarios include:

  • API requests
  • Fetching user profiles
  • Loading dashboard data
  • Delayed retries
  • File and database reads

This is a bad idea when multiple independent async tasks should run in parallel. In that case, Promise.all() is usually faster.

Prerequisites

You only need:

  • A JavaScript file or browser console
  • Basic promises knowledge
  • Familiarity with fetch()

Step-by-step instructions

Step 1: Mark the function as async and use await

Start by adding async before the function.

JavaScript

async function loadUser() {
  const response = await fetch("/api/user");
  const user = await response.json();

  console.log(user);
}

await pauses inside the async function until the promise resolves.

A common real-world pattern is returning the loaded data.

JavaScript

async function getProducts() {
  const response = await fetch("/api/products");
  return await response.json();
}

Wrap async code in try...catch when failures are possible.

JavaScript

async function loadDashboard() {
  try {
    const response = await fetch("/api/stats");
    const stats = await response.json();
    console.log(stats);
  } catch (error) {
    console.error(error);
  }
}

What to look for:

  • await works only inside async functions
  • await pauses until the promise resolves
  • Great for readable API flows
  • Use try...catch for failed requests
  • Parallel requests may need Promise.all()

Examples you can copy

Fetch user data

JavaScript

async function getUser() {
  const response = await fetch("/api/user");
  return await response.json();
}

Load posts

JavaScript

async function loadPosts() {
  const response = await fetch("/api/posts");
  const posts = await response.json();
  console.log(posts);
}

Retry after delay

JavaScript

async function retryLater() {
  await new Promise(resolve => setTimeout(resolve, 1000));
  fetchData();
}

Common mistakes and how to fix them

Mistake 1: Using await outside an async function

What the reader might do:

JavaScript

const data = await fetch("/api/user");

Why it breaks: await only works inside async functions or supported module contexts.

Corrected approach:

JavaScript

async function load() {
  const data = await fetch("/api/user");
}

Mistake 2: Forgetting to await .json()

What the reader might do:

JavaScript

const data = response.json();
console.log(data);

Why it breaks: response.json() returns a promise.

Corrected approach:

JavaScript

const data = await response.json();

Mistake 3: Missing error handling

What the reader might do:

JavaScript

async function load() {
  const response = await fetch("/api/user");
}

Why it breaks: failed requests can reject and stop execution.

Corrected approach:

JavaScript

try {
  const response = await fetch("/api/user");
} catch (error) {
  console.error(error);
}

Troubleshooting

If await throws a syntax error, confirm the function is marked async.

If the logged value is a promise, check for a missing await.

If failed requests crash the flow, add try...catch.

If multiple requests feel slow, use Promise.all() for parallel loading.

Quick recap

  • Mark the function with async
  • Use await for promise results
  • await works only in async functions
  • Wrap risky calls in try...catch
  • Use Promise.all() for parallel tasks