Skip to main content

Command Palette

Search for a command to run...

Async/Await in JavaScript: Writing Cleaner Asynchronous Code

Updated
4 min read
Async/Await in JavaScript: Writing Cleaner Asynchronous Code
S
A front-end developer who’s always learning, building projects, and writing blogs to simplify web concepts

When you start working with asynchronous code in JavaScript, things can become hard to manage. Callbacks can get messy, and even promises can feel confusing when you chain many steps together.

To solve this, async/await was introduced. It helps you write asynchronous code in a way that looks simple and easy to follow.


Why Async/Await Was Introduced

Before using async/await :

  • Callbacks, which often became difficult to manage

  • Promises, which improved things, but still created long chains

Example using promises:

fetchData()
  .then(data => processData(data))
  .then(result => saveData(result))
  .catch(err => handleError(err));

This works fine, but as your logic grows, it becomes harder to read.

Async/await was designed to simplify this process. It lets you write code in a straightforward, step-by-step manner, making it easier to understand.


How Async Functions Work

An async function always returns a promise.

async function example() {
  return "Hello";
}

Even though it looks like a normal return, it actually returns a promise.

example().then(res => console.log(res)); // Hello

So you can think of async functions as a simpler way to work with promises.


The Await Keyword

The await keyword is used inside async functions. It pauses the function until the promise is completed.

async function getData() {
  let response = await fetch("https://api.example.com/data");
  let data = await response.json();
  console.log(data);
}

What happens in this code is that fetching data from an API can take some time. The response does not come instantly, so we use asynchronous code to handle this delay.

The await keyword tells JavaScript to wait until the data is received before moving to the next line. First, it waits for the response from the API. Then it waits again to convert that response into usable data.

In simple terms, it is saying: wait until the data is ready, then continue executing the rest of the code.


Error Handling with Async Code

With promises, you use .catch() to handle errors.

With async/await, you can use try...catch, which is more familiar.

async function getData() {
  try {
    let response = await fetch("https://api.example.com/data");
    let data = await response.json();
    console.log(data);
  } catch (error) {
    console.log("Error:", error);
  }
}

This keeps your error handling clean and in one place.


Comparison: Promises vs Async/Await

Using Promises

fetch("https://api.example.com/data")
  .then(res => res.json())
  .then(data => console.log(data))
  .catch(err => console.log(err));

Using Async/Await

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);
  }
}

Key Difference

  • Promises use chaining

  • Async/await uses a step by step flow

  • Async/await is easier to read and debug.


Async/Await as Syntactic Sugar

Async/await does not replace promises. It is built on top of them.

This means:

  • Promises are still used behind the scenes

  • Async/await only changes how you write the code

So instead of chaining .then(), you write simpler and cleaner code.


How It Improves Readability

Async/await makes your code much easier to follow because it runs in a clear, step by step order. Instead of jumping between multiple .then() calls, everything is written in a single flow, which makes the logic more structured. It also looks very similar to normal synchronous code, so it feels more natural to read and understand. On top of that, handling errors becomes simpler since you can use try...catch in one place. Overall, this approach reduces confusion and makes your code cleaner and more maintainable.


Flow Diagram


Conclusion

Async/await simplifies working with asynchronous code by eliminating the complexity of lengthy promise chains, allowing you to write logic in a clear, step-by-step manner. Once you grasp its functionality, managing APIs and other asynchronous tasks becomes much easier and more efficient.

JavaScript Journey: From Basics to Core Concepts

Part 18 of 29

This series documents my journey of learning JavaScript and breaking down important concepts in a simple way. Each article covers a core JavaScript topic with clear explanations and beginner-friendly examples. From basic concepts to essential JavaScript features, the goal of this series is to make JavaScript easier to understand while practicing and sharing what I learn.

Up next

Synchronous vs Asynchronous JavaScript

JavaScript execution may appear simple at first because it runs line by line. However, as applications grow, some operations do not follow a strict sequence. This introduces the concepts of synchronou