Last updated: 2026-05-05

Asynchronous JavaScript

In JavaScript, asynchronous programming allows code to perform non-blocking operations. This means the program can continue executing other tasks while waiting for long-running operations—like fetching data, reading files, or interacting with a database—to complete.


Synchronous vs. Asynchronous

1. Synchronous (Blocking)

Tasks are executed one after another. If a task takes time, it blocks the rest of the code from running.

console.log("Task 1");
console.log("Task 2");
console.log("Task 3");
// Output: Task 1, Task 2, Task 3 (In order)

2. Asynchronous (Non-blocking)

Tasks that take time are executed in the background. The program continues without waiting for them to finish.

console.log("Task 1");
setTimeout(() => console.log("Task 2 (after 2s)"), 2000);
console.log("Task 3");
// Output: Task 1, Task 3, Task 2

Callbacks

A callback is a function passed as an argument to another function. It is executed after the first function has finished its task.

Simple Callback

function greet(name, callback) {
    console.log(`Hello, ${name}!`);
    callback();
}

function sayGoodbye() {
    console.log("Goodbye!");
}

greet("Alice", sayGoodbye);

Callback for Async Operations

Callbacks are common for handling data that takes time to arrive.

function fetchData(callback) {
    setTimeout(() => {
        const data = { id: 1, name: "Alice" };
        callback(data);
    }, 2000);
}

fetchData((data) => console.log("Processing:", data));

Warning: Nesting many callbacks inside one another leads to "Callback Hell," making code hard to read and maintain.


Promises

Promises were introduced to fix "Callback Hell." A Promise represents a value that will be available in the future.

The Three States of a Promise:

  1. Pending: Initial state, operation in progress.
  2. Fulfilled: Operation completed successfully (resolve).
  3. Rejected: Operation failed (reject).
let myPromise = new Promise((resolve, reject) => {
  let success = true;
  if (success) resolve("Success!");
  else reject("Failure!");
});

myPromise
  .then(result => console.log(result)) // Runs on resolve
  .catch(error => console.log(error));  // Runs on reject

Async / Await

Introduced in ES8 (ECMAScript 2017) — two versions after ES6 — async/await is modern syntax built on top of Promises. It makes asynchronous code look and behave more like synchronous code, which is easier to read and debug. You may have seen it introduced alongside ES6 features elsewhere; while it is part of the same modern JavaScript ecosystem, it arrived slightly later.

How it Works:

  • async keyword: Declares that a function is asynchronous and always returns a Promise.
  • await keyword: Tells JavaScript to pause the function execution until the Promise resolves.
function fetchData() {
  return new Promise(resolve => {
    setTimeout(() => resolve("Data loaded"), 1000);
  });
}

async function loadData() {
  console.log("Loading...");
  const result = await fetchData(); // Pauses here until data arrives
  console.log(result); 
}

loadData(); 

Error Handling with async/await

Just as Promises use .catch() to handle rejections, async/await uses a try/catch block. The try block contains the code to attempt, and catch handles any errors if the awaited Promise rejects.

function fetchData() {
  return new Promise((resolve, reject) => {
    const success = false;
    setTimeout(() => {
      if (success) resolve("Data loaded");
      else reject("Failed to load data");
    }, 1000);
  });
}

async function loadData() {
  try {
    const result = await fetchData();
    console.log(result); // Runs if Promise resolves
  } catch (error) {
    console.log("Error:", error); // Runs if Promise rejects
    // Output: Error: Failed to load data
  }
}

loadData();

Without try/catch, a rejected Promise inside an async function will throw an unhandled error that can crash the program silently.

Why it Matters:

  • Avoids .then() chains: No more messy nesting.
  • Linear logic: Code reads from top to bottom.
  • Scope: await only works inside async functions.