Skip to content

6. Async JavaScript (SUPER IMPORTANT)

Async JavaScript is one of the most important topics in frontend interviews.

It is heavily used in:

  • API calls
  • React applications
  • Timers
  • User interactions
  • Backend communication

Interviewers frequently ask about:

  • Promises
  • async/await
  • Event loop
  • Callback queue
  • Microtask queue

Topics Covered

  • Synchronous vs Asynchronous
  • Callbacks
  • Callback Hell
  • Promise
  • Promise Methods
  • async/await
  • Fetch API
  • Event Loop
  • Call Stack
  • Callback Queue
  • Microtask Queue
  • setTimeout

1. Synchronous vs Asynchronous


Synchronous Code

Code executes line by line.

Next line waits for previous line to finish.

Example

js
console.log("Start");

console.log("Middle");

console.log("End");

Output

js
Start;
Middle;
End;

Asynchronous Code

Does not block execution.

Tasks can run later while other code continues.

Example

js
console.log("Start");

setTimeout(() => {
  console.log("Async Task");
}, 2000);

console.log("End");

Output

js
Start
End
Async Task

2. Callback Function

A callback is a function passed into another function.

Used heavily in asynchronous JavaScript.


Example

js
function greet(name, callback) {
  console.log("Hello " + name);

  callback();
}

function done() {
  console.log("Completed");
}

greet("Dipak", done);

Output

js
Hello Dipak
Completed

Why Callbacks are Used

  • API calls
  • Event handling
  • Timers
  • Async operations

Example with setTimeout

js
setTimeout(() => {
  console.log("Executed after 2 seconds");
}, 2000);

3. Callback Hell

When multiple nested callbacks make code difficult to read.


Example

js
setTimeout(() => {
  console.log("Step 1");

  setTimeout(() => {
    console.log("Step 2");

    setTimeout(() => {
      console.log("Step 3");
    }, 1000);
  }, 1000);
}, 1000);

Problem with Callback Hell

  • Hard to read
  • Difficult to debug
  • Difficult to maintain

Promises were introduced to solve this problem.


4. Promise (VERY IMPORTANT)

A Promise represents future completion or failure of an asynchronous operation.


Promise States

StateMeaning
PendingInitial state
FulfilledOperation successful
RejectedOperation failed

Basic Syntax

js
const promise = new Promise((resolve, reject) => {
  resolve("Success");
});

Example

js
const promise = new Promise((resolve, reject) => {
  let success = true;

  if (success) {
    resolve("Data fetched");
  } else {
    reject("Error occurred");
  }
});

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

Output

js
Data fetched

.then() and .catch()

MethodPurpose
.then()Handles success
.catch()Handles errors
.finally()Runs always

Promise Chaining

js
Promise.resolve(5)
  .then((num) => num * 2)
  .then((num) => num + 1)
  .then((result) => {
    console.log(result);
  });

Output

js
11;

5. Promise Methods


Promise.all()

Runs multiple promises together.

Fails if any promise fails.


Example

js
Promise.all([Promise.resolve("A"), Promise.resolve("B")]).then((data) => {
  console.log(data);
});

Output

js
["A", "B"];

Promise.race()

Returns first completed promise.


Example

js
Promise.race([
  new Promise((res) => setTimeout(() => res("First"), 1000)),
  new Promise((res) => setTimeout(() => res("Second"), 2000)),
]).then((data) => {
  console.log(data);
});

Output

js
First;

6. async/await (VERY IMPORTANT)

async/await is cleaner syntax for handling promises.


async

Makes function return a promise automatically.


await

Waits for promise to resolve.


Example

js
async function getData() {
  const res = await fetch("api");

  const data = await res.json();

  console.log(data);
}

Why async/await is Better

  • Cleaner syntax
  • Easier to read
  • Looks synchronous
  • Better error handling

Error Handling with try...catch

js
async function getData() {
  try {
    const res = await fetch("api");

    const data = await res.json();

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

7. Fetch API

Used to make HTTP requests.


GET Request Example

js
fetch("https://api.com/users")
  .then((res) => res.json())
  .then((data) => {
    console.log(data);
  });

async/await Version

js
async function getUsers() {
  const res = await fetch("https://api.com/users");

  const data = await res.json();

  console.log(data);
}

8. setTimeout()

Schedules code after delay.


Example

js
setTimeout(() => {
  console.log("Executed later");
}, 1000);

Important Point

setTimeout does NOT guarantee exact timing.

It only guarantees minimum delay.


9. Event Loop (VERY IMPORTANT)

JavaScript is single-threaded.

It can do one thing at a time.

The Event Loop helps handle asynchronous operations.


Main Components of Event Loop


1. Call Stack

Tracks currently executing functions.

Functions are pushed and popped from stack.


Example

js
function one() {
  two();
}

function two() {
  console.log("Hello");
}

one();

Stack Flow

txt
Call Stack

one()
two()
console.log()

2. Web APIs

Browser handles async tasks here.

Examples:

  • setTimeout
  • DOM events
  • Fetch API

3. Callback Queue

Stores callback functions from async operations.

Example:

js
setTimeout(() => {
  console.log("Done");
}, 1000);

After timer finishes, callback moves to callback queue.


4. Microtask Queue (VERY IMPORTANT)

Higher priority queue.

Stores:

  • Promise callbacks
  • MutationObserver

Example

js
Promise.resolve().then(() => {
  console.log("Promise");
});

Event Loop Working

Event loop checks:

  1. Is call stack empty?
  2. If yes:
    • First execute microtask queue
    • Then execute callback queue

MOST ASKED INTERVIEW QUESTION

Output Prediction

js
console.log("Start");

setTimeout(() => {
  console.log("Timeout");
}, 0);

Promise.resolve().then(() => {
  console.log("Promise");
});

console.log("End");

Output

js
Start;
End;
Promise;
Timeout;

Why?

Step 1

Synchronous code runs first.

js
Start;
End;

Step 2

Promise callback goes into microtask queue.

js
Promise;

Step 3

setTimeout callback goes into callback queue.

js
Timeout;

Important Rule

Microtask queue executes BEFORE callback queue.


Visual Flow of Event Loop

txt
Call Stack

Web APIs

Microtask Queue (High Priority)

Callback Queue

Event Loop

Important Interview Questions


Q1. What is a Promise?

A Promise represents future completion or failure of an async operation.

States:

  • Pending
  • Fulfilled
  • Rejected

Q2. Difference Between Callback and Promise

CallbackPromise
Nested structureCleaner chaining
Hard to manageBetter readability
Callback hellAvoids callback hell

Q3. What is async/await?

Cleaner way to handle promises.

await pauses execution until promise resolves.


Q4. Explain Event Loop

Event loop handles async operations in JavaScript.

Main parts:

  • Call stack
  • Web APIs
  • Microtask queue
  • Callback queue

Q5. Difference Between Microtask Queue and Callback Queue

Microtask QueueCallback Queue
Higher priorityLower priority
Promise callbackssetTimeout
Runs firstRuns later

Most Important Topics for Interviews

Focus heavily on:

  • Promise
  • async/await
  • Event loop
  • Microtask queue
  • setTimeout
  • Fetch API
  • Callback hell

Best Practices

  • Prefer async/await over nested callbacks
  • Always handle promise errors
  • Understand event loop deeply
  • Avoid callback hell
  • Use Promise.all() for parallel requests

© 2025 DDocs · Dipak's Documentation Guide