CS Engineering Gyan

Asynchronous JavaScript

Asynchronous JavaScript is an important concept that allows programs to perform tasks without blocking the execution of other code. It enables JavaScript applications to handle time-consuming operations efficiently.

Operations such as fetching data from servers, loading files, animations, timers, and database communication may take time to complete. Asynchronous programming allows JavaScript to continue executing other tasks while waiting for these operations.

Modern websites and applications heavily depend on asynchronous JavaScript to provide fast and responsive user experiences.


What is Asynchronous JavaScript?

Asynchronous JavaScript is a programming technique where tasks are started and completed independently from the main program execution flow.

Instead of waiting for a slow operation to finish, JavaScript continues executing the remaining code and handles the result when the operation completes.

Example of Asynchronous Tasks


Synchronous vs Asynchronous JavaScript

JavaScript programs can execute code in two different ways: synchronous and asynchronous.

Synchronous JavaScript Asynchronous JavaScript
Executes code line by line. Allows multiple tasks to run without blocking.
Next task waits until previous task completes. Next task can execute while waiting.
Simple but slower for heavy operations. Improves application performance.
Used for normal calculations. Used for API calls and network operations.

Why Do We Need Asynchronous JavaScript?

JavaScript runs in a single thread, meaning it can execute one task at a time. If a slow operation blocks execution, the entire webpage may become unresponsive.

Asynchronous programming solves this problem by allowing JavaScript to handle long-running tasks efficiently.

Advantages of Asynchronous JavaScript


JavaScript Execution Model

JavaScript uses an execution model based on the call stack, Web APIs, callback queue, and event loop to manage asynchronous operations.

Important Components

Component Purpose
Call Stack Executes JavaScript code.
Web APIs Handles browser-provided operations like timers and requests.
Callback Queue Stores completed asynchronous tasks.
Event Loop Moves completed tasks to the call stack.

JavaScript Event Loop

The event loop is a mechanism that allows JavaScript to perform asynchronous operations while maintaining single-thread execution.

It continuously checks whether the call stack is empty. If an asynchronous task is completed, the event loop moves its callback function into the call stack for execution.

Example


console.log("Start");


setTimeout(function()
{

console.log("Timer Completed");


},2000);


console.log("End");


Output


Start

End

Timer Completed

The timer does not block the execution of other statements. JavaScript continues running and executes the callback later.


JavaScript setTimeout() Function

The setTimeout() function executes a function after a specified amount of time.

Syntax


setTimeout(function, milliseconds);


Example


setTimeout(
function()
{

console.log("Hello JavaScript");

},
3000
);


The message will be displayed after 3 seconds.


Callbacks in JavaScript

A callback is a function passed as an argument to another function. It is executed after a particular task is completed.

Callbacks are one of the earliest methods used for handling asynchronous operations in JavaScript.

Example


function message(callback)
{

console.log("Processing...");


callback();


}


function complete()
{

console.log("Task Completed");

}


message(complete);


Output


Processing...

Task Completed


Callback with setTimeout()


function downloadFile(callback)
{


setTimeout(
function()
{

console.log("File Downloaded");

callback();

},
2000
);


}


downloadFile(
function()
{

console.log("Opening File");

}

);




Callback Hell in JavaScript

Callbacks are useful for handling asynchronous operations, but when multiple asynchronous tasks depend on each other, the code can become difficult to read and maintain. This situation is known as Callback Hell.

Callback Hell occurs when callbacks are nested inside other callbacks multiple times, creating a pyramid-like structure. It makes debugging and managing code more difficult.

Example of Callback Hell


function getUser(callback)
{

setTimeout(function()
{

console.log("User Data Loaded");


callback();


},1000);

}



function getOrders(callback)
{

setTimeout(function()
{

console.log("Orders Loaded");


callback();


},1000);

}



function getPayment(callback)
{

setTimeout(function()
{

console.log("Payment Completed");


callback();


},1000);


}



getUser(function()
{


getOrders(function()
{


getPayment(function()
{


console.log("Process Completed");


});


});


});


Output


User Data Loaded

Orders Loaded

Payment Completed

Process Completed


Problems with Callback Functions

Although callbacks are useful, they have some limitations when applications become complex.

To solve these problems, JavaScript introduced Promises.


Introduction to JavaScript Promises

A Promise is a modern JavaScript feature used to handle asynchronous operations in a cleaner and more organized way.

A Promise represents a value that may be available now, in the future, or may fail with an error.

Promises make asynchronous code easier to write and manage compared to traditional callbacks.


Promise States in JavaScript

A Promise can have three different states during its lifecycle.

State Description
Pending Initial state when the asynchronous operation has not completed.
Fulfilled Operation completed successfully and returned a result.
Rejected Operation failed and returned an error.

Creating a Promise

A Promise is created using the Promise constructor. It accepts a function with two parameters: resolve and reject.

Syntax


let promise = new Promise(
function(resolve,reject)
{

// asynchronous operation

});



Example of Promise


let download = new Promise(
function(resolve,reject)
{


let completed = true;


if(completed)
{

resolve("Download Completed");

}

else
{

reject("Download Failed");

}


});



Handling Promise Result Using then()

The then() method is executed when a Promise is successfully completed.

Example


download.then(
function(result)
{

console.log(result);

});


Output


Download Completed


Handling Errors Using catch()

The catch() method handles errors when a Promise is rejected.

Example


download.catch(
function(error)
{

console.log(error);

});



finally() Method in Promise

The finally() method executes code after a Promise is completed, whether it succeeds or fails.

It is commonly used for cleanup operations such as hiding loading indicators.

Example


download

.then(
result =>
{

console.log(result);

})

.catch(
error =>
{

console.log(error);

})

.finally(
function()
{

console.log("Process Finished");

});



Promise Chaining

Promise chaining allows multiple asynchronous operations to be executed one after another.

Instead of creating deeply nested callbacks, promises provide a cleaner approach.

Example


function stepOne()
{

return Promise.resolve(
"Step One Completed"
);

}


function stepTwo(data)
{

console.log(data);


return Promise.resolve(
"Step Two Completed"
);

}



stepOne()

.then(stepTwo)

.then(
result =>
{

console.log(result);

});


Output


Step One Completed

Step Two Completed


Promise Methods

JavaScript provides several built-in Promise methods for handling multiple asynchronous operations.

Method Purpose
Promise.all() Waits for multiple promises to complete.
Promise.race() Returns the result of the first completed promise.
Promise.allSettled() Returns results after all promises finish.
Promise.any() Returns the first successful promise.

Promise.all() Example


let first =
Promise.resolve("First Task");


let second =
Promise.resolve("Second Task");



Promise.all(
[first,second]

)

.then(
function(result)
{

console.log(result);

});


Output


[
"First Task",
"Second Task"
]


Promises vs Callbacks

Callbacks Promises
Older asynchronous approach. Modern asynchronous approach.
Can create callback hell. Provides cleaner chaining.
Error handling is difficult. Uses catch() for errors.
Less readable for complex tasks. Better for large applications.

Real-World Applications of Promises


Best Practices for Using Promises



Async Functions in JavaScript

Async functions are a modern way to write asynchronous JavaScript code. They were introduced in ES8 and provide a simpler syntax for working with promises.

An async function always returns a Promise. It allows developers to write asynchronous code that looks similar to normal synchronous code.

Syntax of Async Function


async function functionName()
{

// asynchronous code

}


Example of Async Function


async function message()
{

return "Welcome to JavaScript Async Programming";

}


message()

.then(
function(result)
{

console.log(result);

}

);


Output


Welcome to JavaScript Async Programming

The async keyword automatically converts the returned value into a Promise.


Await Keyword in JavaScript

The await keyword is used inside an async function to wait for a Promise to complete before moving to the next statement.

It makes asynchronous code easier to understand because developers can write code in a step-by-step manner.

Syntax


let result = await promise;


Example of await Keyword


function getData()
{

return new Promise(
function(resolve)
{

setTimeout(
function()
{

resolve("Data Received");

},
2000
);

});

}



async function displayData()
{

let result = await getData();


console.log(result);

}


displayData();

Output


Data Received

The await keyword pauses the async function until the Promise is completed.


Async/Await Error Handling

Errors in async functions can be handled using try...catch statements.

The try block contains asynchronous code, while the catch block handles possible errors.

Example


async function fetchData()
{


try
{

let result =
await getData();


console.log(result);

}


catch(error)
{

console.log(error);

}


}



Advantages of Async/Await


Fetch API in JavaScript

The Fetch API is a modern JavaScript feature used to communicate with servers and retrieve data from external resources.

It allows applications to send HTTP requests and receive responses without refreshing the webpage.

Fetch API works with Promises, making it suitable for asynchronous programming.


Syntax of Fetch API


fetch(url)

.then(response =>
{

return response;

})

.then(data =>
{

console.log(data);

})

.catch(error =>
{

console.log(error);

});



Example: Fetch Data from API


fetch(
"https://example.com/data"
)


.then(
response =>
response.json()

)


.then(
data =>
{

console.log(data);

}

)


.catch(
error =>
{

console.log(error);

}

);


The fetch() function sends a request to the given URL and returns a Promise.


Using Fetch API with Async/Await

Async/await provides a cleaner way to work with Fetch API.

Example


async function getUsers()
{


try
{


let response =
await fetch(
"https://example.com/users"
);



let users =
await response.json();



console.log(users);



}

catch(error)
{

console.log(error);

}


}


getUsers();


HTTP Request Methods

Fetch API supports different HTTP methods for communication with servers.

Method Purpose
GET Used to retrieve data from a server.
POST Used to send new data to a server.
PUT Used to update existing data.
DELETE Used to remove data.

Sending Data Using POST Request


fetch(
"https://example.com/users",
{

method:"POST",

body:
JSON.stringify(
{

name:"Rahul",

age:21

}

),

headers:
{

"Content-Type":
"application/json"

}

}

)


.then(
response =>
response.json()

)


.then(
data =>
console.log(data)

);



Working with JSON Data

JSON (JavaScript Object Notation) is commonly used for exchanging data between client and server.

Most APIs return data in JSON format, which JavaScript can easily process.

JSON Example


{

"name":"Amit",

"course":"JavaScript",

"duration":"3 Months"

}


Convert JSON to JavaScript Object


let jsonData =

'{"name":"Rahul","age":22}';



let objectData =
JSON.parse(jsonData);



console.log(objectData.name);


Output


Rahul


Convert JavaScript Object to JSON


let student =
{

name:"Amit",

age:21

};



let json =
JSON.stringify(student);



console.log(json);



Real-World Applications of Async JavaScript

Asynchronous JavaScript is used in almost every modern web application.


Common Mistakes in Async JavaScript


Best Practices for Asynchronous Programming


Asynchronous JavaScript Interview Questions

  1. What is asynchronous JavaScript?
  2. Difference between synchronous and asynchronous programming?
  3. What is the role of the event loop?
  4. What is a callback function?
  5. What is callback hell?
  6. What is a Promise in JavaScript?
  7. Explain Promise states.
  8. Difference between then() and catch()?
  9. What is async/await?
  10. Why is await used inside async functions?
  11. What is Fetch API?
  12. How do you handle errors in Fetch API?
  13. Difference between Promise and async/await?
  14. What are HTTP request methods?
  15. Why is asynchronous programming important in web development?

Summary

Asynchronous JavaScript allows developers to perform time-consuming operations without blocking the execution of other code. Concepts like callbacks, promises, async/await, and Fetch API are essential for creating modern interactive web applications.

Callbacks introduced asynchronous programming, promises improved code structure, and async/await made asynchronous code easier to understand and maintain.

A strong understanding of asynchronous JavaScript helps developers build fast, responsive, and scalable applications using APIs, databases, and modern frontend technologies.


← Previous: Modern JavaScript (ES6+) Next: JavaScript Best Practices →
Home Visit Our YouTube Channel