Back to blog
JavaScript

Async/Await in JavaScript: Writing Cleaner Asynchronous Code

May 10, 2026 3 min read

Why Async/Await Was Introduced

Before async/await, JavaScript used:

  • Callbacks

  • Promises

Promises improved async handling, but long .then() chains became difficult to read.

Async/await was introduced to make asynchronous code look more like synchronous code.


Async/Await Is Syntactic Sugar

Async/await is built on top of promises.

It does not replace promises internally.

It simply provides cleaner syntax.


Promise Example

function fetchData() {
  return Promise.resolve("Data received");
}

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


Async/Await Version

function fetchData() {
  return Promise.resolve("Data received");
}

async function getData() {
  const data = await fetchData();

  console.log(data);
}

getData();


Why Async/Await Is Cleaner

PromisesAsync/Await
.then() chainsTop-to-bottom flow
More nestingCleaner structure
Harder readabilityEasier readability

Promise vs Async/Await Flow

flowchart TD
    A[Promise .then()] --> B[Callback Chain]

    C[async/await] --> D[Linear Readable Flow]


What Does async Do?

The async keyword makes a function asynchronous.

An async function always returns a promise.


Example

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

greet().then(console.log);


Output

Hello


What Does await Do?

await pauses execution until a promise resolves.

It can only be used inside async functions.


Example

function fetchUser() {
  return Promise.resolve("Ali");
}

async function showUser() {
  const user = await fetchUser();

  console.log(user);
}

showUser();


Output

Ali


Async Function Execution Flow

Diagram: sequenceDiagram

Step-by-Step Understanding

const data = await fetchData();

Means:

Wait until promise finishes
↓
Store resolved value
↓
Continue execution


Real Async Example

function delay() {
  return new Promise((resolve) => {
    setTimeout(() => {
      resolve("Completed");
    }, 2000);
  });
}

async function run() {
  console.log("Start");

  const result = await delay();

  console.log(result);
}

run();


Output

Start
Completed


Error Handling With Async/Await

Use:

try...catch


Example

function fetchData() {
  return Promise.reject("Server Error");
}

async function getData() {
  try {
    const data = await fetchData();

    console.log(data);
  } catch (error) {
    console.log(error);
  }
}

getData();


Output

Server Error


Why Error Handling Matters

Async operations can fail because of:

  • Network issues

  • Database failures

  • Invalid APIs

  • Timeouts


Async Error Flow

Diagram: flowchart TD

Sequential Async Operations

async function process() {
  const user = await getUser();
  const orders = await getOrders();

  console.log(user);
  console.log(orders);
}

Looks synchronous but works asynchronously.


Common Beginner Mistakes

Using await Outside Async Function

Incorrect:

const data = await fetchData();

Correct:

async function test() {
  const data = await fetchData();
}


Forgetting Error Handling

Incorrect:

async function test() {
  const data = await fetchData();
}

Better:

async function test() {
  try {
    const data = await fetchData();
  } catch (error) {
    console.log(error);
  }
}


Real-World Usage

Async/await is heavily used in:

  • API requests

  • Database queries

  • Authentication

  • File handling

  • Express.js backends


Practical Example

async function fetchUsers() {
  try {
    const response = await fetch(
      "https://jsonplaceholder.typicode.com/users"
    );

    const users = await response.json();

    console.log(users);
  } catch (error) {
    console.log(error);
  }
}


Key Takeaways

ConceptSummary
asyncCreates async function
awaitWaits for promise
Async/AwaitCleaner promise syntax
Error HandlingUse try...catch
Main BenefitBetter readability

Final Notes

Async/await became the modern standard for asynchronous JavaScript because it makes async code:

  • Cleaner

  • Easier to read

  • Easier to debug

  • Easier to maintain

Almost all modern JavaScript frameworks and backend applications use async/await extensively.


0 Comments

Sign in to join the conversation

No comments yet. Be the first to comment!