async/await in JavaScript: Making Async Code Readable
Learn how async/await in JavaScript works with clear examples. Understand how it replaces Promise chains, handles errors with try/catch, and makes asynchronous code easier to read.
Async/await in JavaScript transformed the way developers write asynchronous code. Before it existed, handling async operations meant chaining .then() calls that got deeply nested and hard to follow. Now you can write async code that looks synchronous. Let’s break it down.
The Problem async/await Solves
Without async/await, fetching data looked like this:
fetch("/api/users")
.then(response => response.json())
.then(users => {
return fetch(`/api/posts?userId=${users[0].id}`);
})
.then(response => response.json())
.then(posts => console.log(posts))
.catch(error => console.error(error));
With async/await, the same logic reads like regular code:
async function loadUserPosts() {
try {
const usersRes = await fetch("/api/users");
const users = await usersRes.json();
const postsRes = await fetch(`/api/posts?userId=${users[0].id}`);
const posts = await postsRes.json();
console.log(posts);
} catch (error) {
console.error(error);
}
}
Much easier to follow.
How async and await Work
asyncbefore a function makes it return a Promise automaticallyawaitpauses execution inside the function until the Promise resolvesawaitcan only be used inside anasyncfunction
async function greet() {
return "Hello!"; // Automatically wrapped in a Promise
}
greet().then(msg => console.log(msg)); // "Hello!"
Running Tasks in Parallel
A common mistake with async/await is running independent tasks sequentially when they could run in parallel:
// SLOW — waits for each one before starting the next
const user = await getUser(1);
const posts = await getPosts(1);
const comments = await getComments(1);
// FAST — all three start at the same time
const [user, posts, comments] = await Promise.all([
getUser(1),
getPosts(1),
getComments(1)
]);
Use Promise.all() when requests don’t depend on each other.
Conclusion
Async/await in JavaScript makes asynchronous code readable and maintainable. Use async on the function, await on the Promise, and try/catch for error handling. And remember Promise.all() when you have independent async tasks — parallel is almost always faster than sequential.
Read next: Understanding Promises in JavaScript
External resource: MDN — async function
Related Articles
How to Write Clean Functions in JavaScript
Learn how to write clean JavaScript functions that are easy to read, test, and maintain. This guide covers naming, single responsibility, pure functions, and avoiding common pitfalls.
CSS Flexbox in Plain English: A Beginner's Guide
Learn CSS Flexbox with simple, visual explanations. This guide covers display flex, justify-content, align-items, flex-wrap, and practical layouts every developer needs to know.
CSS Grid vs Flexbox: When to Use Which
Learn when to use CSS Grid vs Flexbox with clear examples. Understand the key differences between one-dimensional and two-dimensional layouts to make the right choice every time.