Online Compiler logoOnline Compiler

JavaScript Tutorial

JavaScript Async Await: From Basics to Production Patterns

async/await makes asynchronous code easier to read and maintain. It is built on promises and is widely used in modern JavaScript.

Why this matters

Most apps depend on async operations such as API calls and storage reads. Async/await clarity reduces error-prone callback chains.

Core Async Await Rules

An async function always returns a promise.

await pauses inside async functions until promise settles. Rejections throw errors at await line.

Use try/catch for explicit error handling and predictable user-facing behavior.

Sequential vs Parallel Execution

Sequential await is readable and best when second task depends on first output.

If tasks are independent, Promise.all should be preferred for parallel speed.

Code Examples

Sequential Flow with Try/Catch

async function loadUserPosts(userId) {
  try {
    const userRes = await fetch("https://jsonplaceholder.typicode.com/users/" + userId);
    const user = await userRes.json();

    const postRes = await fetch("https://jsonplaceholder.typicode.com/posts?userId=" + userId);
    const posts = await postRes.json();

    console.log(user.name, posts.length);
  } catch (error) {
    console.error("Load failed:", error.message);
  }
}

loadUserPosts(1);

Readable flow where the second request depends on userId.

Parallel with Promise.all

async function loadDashboard() {
  try {
    const [usersRes, postsRes] = await Promise.all([
      fetch("https://jsonplaceholder.typicode.com/users"),
      fetch("https://jsonplaceholder.typicode.com/posts"),
    ]);
    const [users, posts] = await Promise.all([usersRes.json(), postsRes.json()]);
    console.log(users.length, posts.length);
  } catch (error) {
    console.error("Dashboard error:", error.message);
  }
}

loadDashboard();

Parallel requests reduce total waiting time for independent calls.

Safe Fallback Return

async function loadConfig() {
  try {
    const res = await fetch("/api/config");
    if (!res.ok) throw new Error("Config request failed");
    return await res.json();
  } catch {
    return { theme: "light", beta: false };
  }
}

loadConfig().then(console.log);

Fallback patterns avoid complete UI breakage.

Common Mistakes and Fixes

await outside async function

Wrap logic in async function or supported top-level module context.

Missing try/catch for awaited calls

Use try/catch or handle rejection with .catch.

Sequential awaits for independent tasks

Use Promise.all when tasks do not depend on each other.

Frequently Asked Questions

Is async/await better than promises?

It is usually easier to read. Under the hood it still uses promises.

Can I use await inside for loop?

Yes, but execution becomes sequential. Use Promise.all for parallel behavior where safe.

What happens when awaited promise rejects?

An error is thrown at await line and should be handled in try/catch.

Should async functions always return data?

They return promises by default; return explicit data shape for consistency.

Related JavaScript Topics