Understanding Async/Await in JavaScript
JavaScript is famous for making websites interactive but there is one thing every developer struggles with is handling asynchronous operations.
Imagine, you order chai at a shop, While chaiwala prepares your chai, you don’t stand there. You chat with friends, check your phone. Once chai is ready, you continue.
Thats how JavaScript handles async tasks.
Before async/await, developers used callbacks and later Promises. But complex async code quickly became hard to read. To solve this, JavaScript introduced async/await which was a cleaner and more readable way to work with asynchronous code.
Why Async/Await Was Introduced
Before async/await, developers used Promises like this:
fetchData()
.then((data) => {
return processData(data);
})
.then((result) => {
console.log(result);
})
.catch((error) => {
console.log(error);
});
This works fine for small tasks.
But when multiple async operations are used together code starts looking like confusing and difficult to follow.
Async/await was introduced in ES2017 to:
Improve readability
Make asynchronous code look synchronous
Simplify error handling
Reduce Promise chaining complexity
In simple words
Async/await is syntactic sugar over Promises.
That means it does not replace Promises internally -> it simply provides a cleaner syntax to work with them.
How Async Functions Work
An async function always returns a Promise.
Syntax :
async function greet() {
return "Namaste Developer";
}
Even though we return a string, JavaScript automatically wraps it inside a Promise.
Equivalent Promise version
function greet() {
return Promise.resolve("Namaste Developer!");
}
Understanding the Await Keyword
The await keyword pauses execution of an async function until the Promise resolves.
Here is an example,
function orderChai() {
return new Promise((resolve) => {
setTimeout(() => {
resolve("Chai is Ready");
}, 2000);
});
}
async function serveCustomer() {
console.log("Making chai...");
const result = await orderChai();
console.log(result);
}
serveCustomer();
// OUTPUT
// Making chai...
// (2 second pause)
// Chai is Ready
Here is what happens:
orderChai()returns a Promiseawaitpauses executionJavaScript waits for the Promise to resolve
Execution resumes
Error Handling with Async Code
One of the advantages of async/await is clean error handling. Instead of .catch(), we can use try/catch.
Here is an Example,
function paymentSuccessful() {
return new Promise((resolve, reject) => {
const success = false;
setTimeout(() => {
if (success) {
resolve("Payment Successful");
} else {
reject("Payment Failed");
}
}, 2000);
});
}
async function processPayment() {
try {
const message = await paymentSuccessful();
console.log(message);
} catch (error) {
console.log("Error:", error);
}
}
processPayment();
// OUTPUT
// Error: Payment Failed
Promise vs Async/Await Flow
Using Promises
getUser()
.then((user) => {
return getOrders(user);
})
.then((orders) => {
return processOrders(orders);
})
.catch((err) => {
console.log(err);
});
Using Async/Await
async function handleOrders() {
try {
const user = await getUser();
const orders = await getOrders(user);
const result = await processOrders(orders);
console.log(result);
} catch (err) {
console.log(err);
}
}
Difference
| Promises | Async/Await |
|---|---|
Uses .then() chaining |
Looks synchronous |
| Harder to read in complex flows | Cleaner syntax |
| Nested chains possible | Easier maintenance |
| Error handling split | Centralized with try/catch |
Important Things to Remember
Await Only Works Inside Async Functions
await fetchData(); // Wrong async function getData() { // Correct Way await fetchData(); }Async Functions Always Return Promises
async function test() { return 10; } // ACTUALLY RETURNS Promise { 10 }Await Does Not Block Entire JavaScript. It only pauses the current async function and Other operations continue running normally.
When Should You Use Async/Await?
Use async/await when:
Fetching API data
Reading files Database operations
Delayed tasks
Sequential async operations
Examples :
Loading IPL scores from an API
Processing UPI payments
Fetching weather updates
Uploading Aadhaar documents
Limitations of Async/Await
Although async/await improves readability, it has some drawbacks:
Sequential Execution Can Be Slower
await task1(); await task2(); // Here, task2 waits for task1 // Sometimes running tasks in parallel using Promise.all() is faster. const [user, posts] = await Promise.all([ getUser(), getPosts() ]);Still Based on Promises
Async/await is not a replacement for Promises. Under the hood, it still uses Promises internally.
Conclusion
If you’re learning modern JavaScript, mastering async/await is essential. You’ll use async programming everywhere.
And once you start using async/await, going back to long Promise chains feels like returning from 5G to 2G network.
Thanks for Reading.

