Skip to main content

Command Palette

Search for a command to run...

Async/Await in JavaScript

Writing Cleaner Asynchronous Code

Updated
3 min read
Async/Await in JavaScript
S
Software Developer | Full Stack Developer |

Introduction

JavaScript is single-threaded, but it handles asynchronous operations like APIs, file handling, and timers using powerful patterns. Before modern syntax, developers relied heavily on callbacks and promises — which often led to messy, hard-to-read code. That’s where async/await comes in.

Why Async/Await Was Introduced?

Before async/await, we used:

  • Callbacks → caused callback hell

  • Promises → improved structure but still had chaining complexity

Example with promises:

fetchData()
  .then(data => processData(data))
  .then(result => saveResult(result))
  .catch(error => console.error(error));

This is better than callbacks, but still not as readable as synchronous code.

Async/await was introduced to:

  • Make async code look synchronous

  • Improve readability and maintainability

  • Simplify error handling

How Async Functions Work?

An async function always returns a Promise.

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

This is equivalent to:

function getData() {
  return Promise.resolve("Hello");
}

Key Point:

  • async automatically wraps return values in a Promise

Await Keyword Concept

The await keyword pauses execution until a Promise is resolved.

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

What happens here:

  1. Function execution pauses at await

  2. Promise resolves

  3. Execution resumes with the resolved value

Error Handling with Async Code

With promises:

fetchData()
  .then(data => console.log(data))
  .catch(err => console.error(err));

With async/await:

async function loadData() {
  try {
    const data = await fetchData();
    console.log(data);
  } catch (error) {
    console.error(error);
  } finally {
    console.log("Done");
  }
}

Benefits:

  • Cleaner structure

  • Works like synchronous try...catch

  • Easier debugging

Feature Promises (.then) Async/Await
Syntax Chain-based Sequential
Readability Medium High
Error Handling .catch() try...catch
Debugging Harder Easier

Async/Await = Syntactic Sugar

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

Example:

async function example() {
  return 42;
}

Internally behaves like:

function example() {
  return Promise.resolve(42);
}

So you’re still using promises — just with cleaner syntax.

Simple Example:

Using Promises:

function getNumber() {
  return new Promise(resolve => {
    setTimeout(() => resolve(10), 1000);
  });
}

getNumber().then(num => console.log(num));

Using Async/Await:

async function showNumber() {
  const num = await getNumber();
  console.log(num);
}

showNumber();

Notice how it reads like normal synchronous code.

Simple Example

Using Promises:

function getNumber() {
  return new Promise(resolve => {
    setTimeout(() => resolve(10), 1000);
  });
}

getNumber().then(num => console.log(num));

Using Async/Await:

async function showNumber() {
  const num = await getNumber();
  console.log(num);
}

showNumber();

Notice how it reads like normal synchronous code.

When to Use Async/Await

Use async/await when:

  • You want clean, readable code

  • You are dealing with multiple sequential async calls

  • You need structured error handling

Avoid overusing it when:

  • You need parallel execution (use Promise.all() instead)

Conclusion

Async/await is one of the most important modern JavaScript features. It makes asynchronous code:

  • Cleaner

  • Easier to understand

  • Easier to debug

But remember — it’s just a better way to work with promises, not a replacement.

Debunking Fundamentals of JavaScript

Part 24 of 24

This series contains various blogs which explain the basics of javascript from scratch and give an inside working structure of the scripting language.

Start from the beginning

Understanding Variables and Datatypes in JavaScript

Importance of Variables and Datatypes in JavaScript