Many operations in the real world, such as retrieving data from a server or reading a file, take time to finish. If these operations were synchronous, then we need to wait until the entire task is completed, resulting in a bad user experience. Asynchronous operations enable the program to continue executing other tasks while these operations are complete.
1. Understanding Callbacks
Callbacks are functions passed as arguments to other functions, which are then invoked when the task is complete.
// Example of a callback function
function fetchData(callback) {
setTimeout(() => {
callback("Data fetched from server");
}, 2000);
}
// Using the callback
fetchData((message) => {
console.log(message); // Outputs: Data fetched!
});
Code Explanation
Function Definition:
The function fetchData
is defined to accept one argument, callback
.
callback
is expected to be a function that will be called once the asynchronous operation inside fetchData
is complete.
setTimeout:
Inside fetchData
, there is a call to setTimeout
.
setTimeout
is a built-in JavaScript function that executes a function after a specified delay in milliseconds.
it is used to simulate a delay of 2000 milliseconds (2 seconds) to mimic an asynchronous operation like fetching data from a server.
Callback Invocation:
After the 2-second delay, the anonymous function passed to setTimeout
is executed.
This function calls callback
with the argument "Data fetched from server"
.
This means after the delay, the callback
function will be executed with the provided message.
Calling fetchData:
fetchData
is called with an anonymous function as its argument. This anonymous function takes one parameter, message
.
The anonymous function is the callback function that will be executed once the data is "fetched" (after the 2-second delay).
Callback Execution:
After 2 seconds, setTimeout
triggers the execution of the callback with the message "Data fetched from server"
.
The callback function logs the message to the console.
2. Working with Promises
A promise is an object representing the eventual completion or failure of an asynchronous call. It provides methods to handle asynchronous results and handle errors. It provide a consistent way to handle errors using .catch().
function fetchData() {
return new Promise((resolve, reject) => {
setTimeout(() => {
resolve("Data fetched from server");
}, 2000);
});
}
fetchData()
.then((message) => {
console.log(message); // Outputs: Data fetched!
})
.catch((error) => {
console.error(error);
});
Code Explanation
Function Definition:
The fetchData
function is defined to return a new promise.
A promise is an object that represents an asynchronous operation that will eventually complete or fail.
Creating the Promise:
Inside fetchData
, a new promise is created using new Promise((resolve, reject) => {...})
.
The promise constructor takes a function with two parameters, resolve
and reject
. These are functions that you call when the asynchronous operation completes successfully (resolve
) or fails (reject
).
Simulating an Asynchronous Operation:
The setTimeout
function is used to simulate a delay of 2000 milliseconds (2 seconds), representing an asynchronous operation like fetching data from a server.
After the 2-second delay, the resolve function is called with the message "Data fetched from server"
.
This means the promise is successfully fulfilled after 2 seconds with the specified message.
Calling fetchData:
The fetchData
function is called, which returns a promise.
Handling the Promise:
The .then()
method is chained to the promise returned by fetchData
.
The function passed to .then()
is called when the promise is resolved successfully. It receives the message "Data fetched from server"
and logs it to the console.
Error Handling:
The .catch()
method is chained to handle any errors if the promise is rejected.
If there were an error (for example, if reject
were called inside the promise), the function passed to .catch()
would be called to log the error.
3. Async/Await: Modern Asynchronous JavaScript
Async and Await are powerful keywords used for handling asynchronous operations using promises. Async functions returns a promise and await pauses the execution until Promise is resolved. It simplify asynchronous code and improve readability by making it appear synchronous.
async function fetchData() {
try {
let message = await new Promise((resolve) => {
setTimeout(() => {
resolve("Data fetched from server");
}, 2000);
});
console.log(message); // Outputs: Data fetched!
} catch (error) {
console.error(error);
}
}
fetchData();
Code Explanation
Async Function:
The fetchData
function is declared with the async
keyword. This means it can use await
inside it and it returns a promise.
Try-Catch Block:
The try
block contains code that might throw an error. If an error occurs, the control moves to the catch
block to handle the error.
The catch
block catches and handles any errors that occur inside the try block.
Awaiting a Promise:
Inside the try
block, we have an await
expression. It waits for the promise to resolve before moving to the next line of code.
The promise is created using new Promise((resolve) => {...})
.
The setTimeout
function is used to simulate a delay of 2000 milliseconds (2 seconds), representing an asynchronous operation like fetching data from a server.
After 2 seconds, the promise is resolved with the message "Data fetched from server"
, and this message is assigned to the message
variable.
Logging the Message:
After the promise is resolved, the message is logged to the console using console.log(message)
.
Error Handling:
If an error occurs while waiting for the promise or during any operation in the try
block, the control moves to the catch
block.
The error is logged to the console using console.error(error)
.
Calling the Async Function:
The fetchData
function is called. Since it's an async
function, it runs asynchronously.
Comparison Summary
Callbacks are simple and direct but can lead to messy code and inconsistent error handling.
Promises offer a more structured way to handle asynchronous operations and provide better error handling.
Async/Await builds on promises to provide even cleaner, more readable, and maintainable asynchronous code.
Top comments (2)
Thanks for sharing. Nice explanation
thanks