๐Ÿงต Asynchronous JavaScript
Estimated reading: 4 minutes 199 views

JavaScript โ€” Callbacks, Promises & Async-Await: Mastering Asynchronous Code


Introduction โ€” Tackling Asynchronous JavaScript

In a synchronous world, JavaScript runs one task at a time. But what happens when you fetch data from a server or set a timeout?

That’s where asynchronous programming shinesโ€”and to master it, you must understand Callbacks, Promises, and Async/Await.

By the end of this article, youโ€™ll learn:

  • How JavaScript handles async operations
  • What callbacks are and where they fall short
  • How promises help manage async flow
  • ๐Ÿง˜ How async/await makes async code cleaner and more readable

How JavaScript Handles Asynchronous Tasks

JavaScript uses the Event Loop to handle asynchronous operations like:

  • API calls
  • Timers (setTimeout, setInterval)
  • File reads (Node.js)
  • User interactions

These tasks go through callback queues or microtask queues, allowing the call stack to continue executing other code.


Callbacks โ€“ The First Step to Async

What is a Callback?

A callback is a function passed as an argument to another function, to be executed later.

Example

function fetchData(callback) {
  setTimeout(() => {
    callback("Data loaded");
  }, 1000);
}

fetchData(function(result) {
  console.log(result); //  Data loaded
});

Explanation

  • setTimeout simulates async behavior
  • callback() is executed after 1 second

Drawback โ€“ Callback Hell

getData(function(data) {
  process(data, function(result) {
    save(result, function(response) {
      console.log("Done");
    });
  });
});

๐Ÿ˜ต This nested structure is called Callback Hell โ€” hard to read, maintain, and debug.


Promises โ€“ A Better Way

What is a Promise?

A Promise represents a value that may be available now, later, or never. It has 3 states:

StateMeaning
pendingInitial state, waiting for result
fulfilledOperation completed successfully
rejectedOperation failed

Promise Example

function fetchData() {
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      resolve("Promise Resolved");
    }, 1000);
  });
}

fetchData().then(result => {
  console.log(result); //  Promise Resolved
});

Explanation

  • resolve is called when async task is successful
  • .then() handles success
  • .catch() handles errors

Chaining Promises

fetchUser()
  .then(user => fetchProfile(user.id))
  .then(profile => updateUI(profile))
  .catch(error => console.error(error));

Promises solve callback hell by flattening the async flow and making error handling easier.


๐Ÿง˜ Async / Await โ€“ Syntactic Sugar for Promises

What is Async/Await?

async/await is a modern syntax (ES2017+) that makes async code look synchronous.


Example

async function getData() {
  try {
    const result = await fetchData();
    console.log(result); //  Promise Resolved
  } catch (error) {
    console.error(error);
  }
}

Explanation

  • async declares the function returns a Promise
  • await pauses execution until the promise resolves
  • try/catch is used for error handling

Comparison Table โ€“ Callbacks vs Promises vs Async/Await

FeatureCallbacksPromisesAsync/Await
SyntaxNested, hard to readChainable .then()Clean, readable with await
Error HandlingManual, scattered.catch()try...catch
DebuggabilityHardBetterEasiest
Code MaintenancePoor (Callback Hell)BetterBest
Browser SupportOldestES6+ES2017+

Real-World Example: Fetch API with Async/Await

async function getUserData() {
  try {
    const response = await fetch("https://jsonplaceholder.typicode.com/users/1");
    const user = await response.json();
    console.log(user.name); //  Leanne Graham
  } catch (error) {
    console.error("Failed to fetch:", error);
  }
}

This is cleaner than chaining .then() and handles errors effectively.


Tips & Best Practices

  • Always use try...catch with await to catch rejections
  • Combine async/await with Promise.all() for parallel tasks
  • Donโ€™t mix callbacks and promises unless necessary
  • Avoid long chains of .then()โ€”use async/await instead

FAQs โ€“ Callbacks, Promises, and Async/Await

What is the main drawback of callbacks?

Callback Hell โ€” a deeply nested structure that makes the code difficult to read and debug.

What is a Promise in simple terms?

A Promise is a wrapper around an async operation that lets you handle success (resolve) or failure (reject).

Is async/await better than promises?

Async/await uses promises under the hood, but offers cleaner, more readable syntax.

Can I use await outside of async functions?

No. You must use await only inside an async function or top-level await in ES2022+ modules.

How do I handle multiple async tasks?

Use Promise.all() to run tasks in parallel or for-await-of for serial execution.


Share Now :
Share

JavaScript โ€” Callbacks / Promises / Async-Await

Or Copy Link

CONTENTS
Scroll to Top