Sitemap
Kumarpawanm

Kumarpawanm

Everything You Need to Know About Async JavaScript

6 min readMay 8, 2026

--

Press enter or click to view image in full size

Sync and Async In JS:

Sync (Synchronous):

In synchronous JavaScript, code executes line by line in sequence.
Each operation waits for the previous one to finish before executing.

This means:

  • Tasks are dependent on execution order
  • One task can block the next task
console.log("Line 1");
console.log("Line 2");
console.log("Line 3");

/*
Output:
Line 1
Line 2
lIne 3
*/

Asyn (Asynchronous):

In asynchronous JavaScript, some operations take time to complete, such as:

  • API calls
  • Timers
  • File operations

These operations do not block the main thread.
JavaScript continues executing the remaining code while the async task runs in the background.

This means:

  • Later synchronous code may execute before async code finishes
  • The main thread remains non-blocking
console.log("Start");

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

console.log("End"); // this line will execute before setTimeout

/*
Start
End
Async Operation
*/

How do we convert sync code to async code?

We can convert ‘Synchronous’ code into ‘Asynchronous’ code by moving our code inside time-consuming operations

JavaScript provides asynchronous APIs such as:

  • setTimeout()
  • setInterval()
  • fetch()
  • Promises
  • async/await
  • File system APIs (Node.js)

Synchronous Code

console.log('Start');
console.log('Make Me Async');
conole.log('End');

/*
Here, the code executes line by line synchronously.
Output:
Start
Make Me Async
End
*/

Converting Sync to Async Using setTimeout

console.log('Start');
setTimeout(() => {
console.log('Make Me Async'); // will be printed after 1 second
}, 1000)
conole.log('End');

/*
Now "Make Me Async" is scheduled asynchronously using setTimeout().
Output:
Start
End
Make Me Async
*/

Callback & Callback Hell

Callback:

A callback is a function that is passed as an argument to another function and is executed later when a specific task is completed.

function calculator(num1, num2, callback) {

return callback(num1, num2);

}

function addTwoNumbers(num1, num2) {

return num1 + num2;

}

const result = calculator(2, 3, addTwoNumbers);

console.log(result); // Output: 5

What is Callback Hell?

Callback Hell is a situation where deeply nested callbacks make asynchronous code hard to read and manage, causing the code to grow horizontally like a pyramid.

loginUser(user, () => {

getProfile(() => {

getPosts(() => {

getComments(() => {

console.log("Done");

});

});

});

});

Problems with Callback Hell

  • Poor readability
  • Difficult debugging
  • Hard maintenance
  • Complex error handling

Solution

Callback Hell can be solved using:

  • Promises with .then()
  • async/await
// Using Promises
loginUser(user)
.then(getProfile)
.then(getPosts)
.then(getComments)
.then(() => {
console.log("Done");
})
.catch((err) => {
console.log(err);
});


// Using async/await
async function handleUser() {

try {

const profile = await loginUser(user);

const posts = await getPosts(profile);

const comments = await getComments(posts);

console.log("Done");

} catch (err) {

console.log(err);

}

}

Web Browser API’s

Web APIs are features provided by the browser that allow JavaScript to perform operations that the JavaScript engine itself cannot do.

  • create timers
  • make HTTP requests
  • access the DOM
  • handle user events

These capabilities are provided by the browser through Web APIs.

Common Web APIs

  • setTimeout()
  • setInterval()
  • fetch()
  • DOM APIs
  • Geolocation API
  • Local Storage API
  • WebSocket API

Code Examples


// setTimeout()
setTimeout(() => {
console.log("Timer Completed");
}, 2000)


// setInterval()
let count = 1;

setInterval(() => {

console.log(count);
count++;

}, 1000);


// fetch()
fetch("https://dummy.api/data")
.then((response) => response.json())
.then((data) => {
console.log(data);
});

// DOM API
const button = document.getElementById("btn");

button.addEventListener("click", () => {
console.log("Button Clicked!");
});

Promise

What is Promise?

A Promise is a JavaScript object that represents the eventual completion or failure of an asynchronous operation and its resulting value.

Promise States

  • pending: initial state
  • fulfilled: operation completed successfully
  • rejected: operation failed
const promise = new Promise((resolve, reject) => {

let success = true;

if (success) {
resolve("Task completed");
} else {
reject("Task failed");
}

});

Common Promise Methods

.then() Handles successful result

.catch()Handles errors

.finally()Runs regardless of success/failure

Promise.resolve()Creates resolved promise

Promise.reject()Creates rejected promise

Promise.all()Waits for all promises

Promise.race()Returns first settled promise

Promise.allSettled()Waits for all promises regardless of result

Get Kumarpawanm’s stories in your inbox

Join Medium for free to get updates from this writer.

Promise.any()Returns first fulfilled promise

.then()

const promise = Promise.resolve("Success");

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

.catch()

const promise = Promise.reject("Something went wrong");

promise.catch((err) => {
console.log(err);
});

.finally()

Promise.resolve("Done")
.finally(() => {
console.log("Cleanup completed");
});

Promise.resolve()

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

Promise.reject()

Promise.reject("Error occurred")
.catch((err) => {
console.log(err);
});

Promise.all()

const p1 = Promise.resolve("A");
const p2 = Promise.resolve("B");

Promise.all([p1, p2])
.then((data) => {
console.log(data);
});

Promise.race()

const p1 = new Promise((resolve) => {
setTimeout(() => resolve("First"), 1000);
});

const p2 = new Promise((resolve) => {
setTimeout(() => resolve("Second"), 2000);
});

Promise.race([p1, p2])
.then((data) => {
console.log(data);
});

Promise.allSettled()

const p1 = Promise.resolve("Success");
const p2 = Promise.reject("Failed");

Promise.allSettled([p1, p2])
.then((data) => {
console.log(data);
});

Promise.any()

const p1 = Promise.reject("Error");
const p2 = Promise.resolve("Success");

Promise.any([p1, p2])
.then((data) => {
console.log(data);
});

Inversion of control

Inversion of Control means transferring the control of execution from your code to another system, function, or framework.

In JavaScript, Inversion of Control commonly happens with callbacks.

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

/*
you are giving control of your callback to: setTimeout
you do not control when callback executes
browser controls execution timing
*/

Why IoC Can Become Problematic

  • callback may execute multiple times
  • callback may never execute
  • error handling becomes difficult
  • hard to trust external code
function fetchData(callback) {

setTimeout(() => {

callback("Data received");

}, 2000);

}

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

/*
Here:
fetchData controls when callback runs
your callback execution depends on another function
*/

How Promises Solve This

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

Promises guarantee:

  • callback runs once
  • value cannot change unexpectedly
  • better error handling

Event Loop in JS

The Event Loop is a mechanism in JavaScript that continuously monitors the Call Stack and task queues to manage asynchronous operations.

Why Do We Need the Event Loop?

JavaScript executes only one task at a time because it has:

  • one Call Stack
  • one main thread

But JavaScript also supports:

  • timers
  • API calls
  • DOM events
  • promises

The Event Loop coordinates the execution of asynchronous tasks by moving them from task queues to the Call Stack.

Main Components

callstack: Executes synchronous code

Web APIs: Handle async operations

Callback Queue: Stores macrotasks

Microtask Queue: Stores promise callbacks

Code Example

console.log("Start");

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

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

console.log("End");

/*
Output:
Start
End
Promise
Timer
*/

/*
*Step-by-Step Execution*

1. console.log("Start")
Runs immediately.
Output: Start

2. setTimeout()
Timer registered in Web APIs
Callback waits in Callback Queue later

3. Promise.then()
Promise callback goes into: Microtask Queue

4. console.log("End")
Runs immediately.
Output: End

5. Call Stack Becomes Empty
Now Event Loop starts checking queues.
Priority Order:
Microtask Queue
↓
Callback Queue

6. Promise Callback Executes
Output: Promise

7. setTimeout Callback Executes
Output: Timer

*/

Fetch API

What is Fetch API?

fetch() is a Web API used to make HTTP requests in JavaScript.

It returns a Promise.

fetch(url, options)
/*
url → API endpoint
options → request configuration
*/

Common HTTP Methods

GETRetrieve data

POSTCreate data

PUTUpdate the entire resource

PATCHUpdate partial resource

DELETEDelete resource

Code Examples

GET Request

fetch("https://jsonplaceholder.typicode.com/posts/1")
.then((res) => res.json())
.then((data) => {
console.log(data);
});

POST Request

fetch("https://jsonplaceholder.typicode.com/posts", {

method: "POST",

headers: {
"Content-Type": "application/json"
},

body: JSON.stringify({
title: "JavaScript",
body: "Learning fetch API"
})

})
.then((res) => res.json())
.then((data) => {
console.log(data);
});

PUT Request

fetch("https://jsonplaceholder.typicode.com/posts/1", {

method: "PUT",

headers: {
"Content-Type": "application/json"
},

body: JSON.stringify({
id: 1,
title: "Updated Title",
body: "Updated Body"
})

})
.then((res) => res.json())
.then((data) => {
console.log(data);
});

DELETE Request

fetch("https://jsonplaceholder.typicode.com/posts/1", {

method: "DELETE"

})
.then((res) => {
console.log("Deleted Successfully");
});

Error Handling in Async Code

Error Handling with Callbacks


function findUserByUserName(userName, callback){

setTimeout(() => {

if (userName) {
callback(null, "User Data");
} else {
callback(new Error("Invalid user name!"), null);
}

}, 1000);
}


findUserByUserName('user@gmail.com', (err, data) => {

if (err) {
console.log(err.message);
return;
}

console.log(data);
})

Error Handling with Promises

const promise = new Promise((resolve, reject) => {

const success = false;

if (success) {
resolve("Task Completed");
} else {
reject(new Error("Task Failed"));
}

});

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

Error Handling with async/await

async function getData() {

try {

const response = await fetch("https://invalid-url.com");

const data = await response.json();

console.log(data);

} catch (err) {

console.log("Error:", err.message);

}

}

getData();

Error Handling inside setTimeout

setTimeout(function() {
try {
var result = JSON.parse("invalid json");
console.log(result);
} catch (error) {
console.error("Parsing failed:", error.message);
}
}, 1000);

--

--