Async/Await in JavaScript: Writing Cleaner Asynchronous Code

Learning web development in public. Writing simple, real-world explanations about web development concepts. Helping beginners understand why things work, not just how.
Search for a command to run...

Learning web development in public. Writing simple, real-world explanations about web development concepts. Helping beginners understand why things work, not just how.
No comments yet. Be the first to comment.
Every day, millions of users upload photos, videos, stories, and reels to Instagram. From a user's perspective, the process appears simple: select media, apply filters, add a caption, and tap "Post."
Building Offline-First Messaging Apps: How Messages Work Without Internet Modern messaging applications have transformed the way people communicate. Whether it's chatting with friends, collaborating w
In this article we'll explore about the Expo Router and React Navigation and answer which one to use in 2026. If you build mobile apps using React Native, one thing becomes obvious very quickly: Navig

Modern mobile apps are no longer just a collection of screens connected together. Apps like Instagram, WhatsApp, Uber, and Netflix operate at massive scale with millions of users, real time systems, o
In this article we'll be exploring react.js and the things of react.js that makes it popular and stand out among other libraries ( no fight over library vs framework ). We'll go through: What problem

Shkaai
68 posts
In this article we'll understand the async-await keyword of JavaScript. Before understanding what something is, it is always a good idea to know why it exist at all. So to answer that question look at this code which isn't using async-await keyword:
function fetchUser() {
fetch("https://api.example.com/user")
.then(response => response.json())
.then(data => {
console.log("User:", data);
return fetch(`https://api.example.com/posts/${data.id}`);
})
.then(response => response.json())
.then(posts => {
console.log("Posts:", posts);
})
.catch(err => {
console.log("Error:", err);
});
}
At first glance, this might look fine. But as the logic grows:
Multiple .then() chains make it harder to follow
Error handling becomes less intuitive
Code readability decreases
This is exactly why async/await was introduced
Async/await is syntactic sugar over Promises.
It doesn’t replace Promises — it simply provides a cleaner and more readable way to write asynchronous code.
Deep .then() chaining
Callback-like nesting
Difficult debugging in complex flows
An async function always returns a Promise.
async function greet() {
return "Hello";
}
This is equivalent to:
function greet() {
return Promise.resolve("Hello");
}
Even if you return a normal value, JavaScript wraps it inside a Promise.
The await keyword can only be used inside an async function.
It pauses execution until a Promise is resolved.
async function fetchUser() {
let response = await fetch("https://api.example.com/user");
let data = await response.json();
console.log("User:", data);
let postResponse = await fetch(`https://api.example.com/posts/${data.id}`);
let posts = await postResponse.json();
console.log("Posts:", posts);
}
No .then() chaining
Step-by-step execution
Much easier to read and understand
It looks like synchronous code, but it’s still asynchronous under the hood.
Instead of .catch(), async/await uses try...catch.
async function fetchUser() {
try {
let response = await fetch("https://api.example.com/user");
let data = await response.json();
let postResponse = await fetch(`https://api.example.com/posts/${data.id}`);
let posts = await postResponse.json();
console.log(posts);
} catch (error) {
console.log("Error:", error.message);
}
}
Cleaner structure
Centralized error handling
Similar to synchronous programming
fetch("https://api.example.com/data")
.then(res => res.json())
.then(data => console.log(data))
.catch(err => console.log(err));
async function getData() {
try {
let res = await fetch("https://api.example.com/data");
let data = await res.json();
console.log(data);
} catch (err) {
console.log(err);
}
}
| Feature | Promises | Async/Await |
|---|---|---|
| Syntax | .then() chains |
Clean & linear |
| Readability | Medium | High |
| Error Handling | .catch() |
try...catch |
Code flows top-to-bottom
Less nesting
Easier to debug
More intuitive for beginners
You write async code the same way you think about it.
Async/await is one of the most important features in modern JavaScript.
It is built on top of Promises
Makes asynchronous code cleaner
Reduces complexity in real-world applications
async → makes a function return a Promise
await → pauses execution until Promise resolves
Works only inside async functions
Uses try...catch for error handling
Improves readability significantly
Once you start using async/await, going back to .then() chains will feel unnecessarily complicated
.