JavaScript is single-threaded, meaning it can only do one thing at a time. Asynchronous programming allows long-running tasks (like API calls or timers) to run in the background without blocking the main thread, ensuring the user interface remains responsive.
A callback is a function passed as an argument to another function, which is then executed after the outer function has completed. This was the traditional way to handle async operations.
function greet(name, callback) {
document.write("Hello, " + name);
// Simulate a delay
setTimeout(callback, 1000);
}
greet("Ragini", function() {
document.write("The callback has been executed!");
});
When multiple nested callbacks are used, it can lead to "Callback Hell" or the "Pyramid of Doom," making code hard to read and maintain.
A Promise is an object representing the eventual completion (or failure) of an asynchronous operation. It has three states: pending, fulfilled, or rejected.
let promise = new Promise((resolve, reject) => {
let success = true;
setTimeout(() => {
if (success) {
resolve("Promise resolved successfully!");
} else {
reject("Promise failed!");
}
}, 1500);
});
promise
.then(result => document.write(result)) // Handles success
.catch(error => document.write(error)); // Handles failure
async/await is modern "syntactic sugar" built on top of Promises. It makes asynchronous code
look and behave more like synchronous code, making it much easier to read and write.
// A function that returns a promise
function wait(ms) {
return new Promise(resolve => setTimeout(resolve, ms));
}
// An async function
async function run() {
try {
document.write("Start");
await wait(2000); // Pauses execution for 2 seconds
document.write("Finished after 2 seconds");
} catch (error) {
console.error("Something went wrong:", error);
}
}
run();
async/await is perfect for fetching data from an API.
async function fetchUserData() {
try {
const response = await fetch('https://jsonplaceholder.typicode.com/users/1');
const user = await response.json();
document.write("User:", user.name);
} catch (error) {
console.error("Could not fetch user:", error);
}
}
fetchUserData();
| Feature | Callback | Promise | Async/Await |
|---|---|---|---|
| Syntax | Nested and complex | Chained with .then() |
Clean and synchronous-like |
| Error Handling | Manual (error-first) | .catch() |
try...catch |
| Readability | Low (Callback Hell) | Good | Excellent |
Test your understanding of Asynchronous JavaScript.
.then() for success and a .catch() for failure.Promise that resolves after 2 seconds..then() to log the result to the console.async function.async function, use await to pause execution until the Promise resolves.async function named fetchTodo.fetch to get data from https://jsonplaceholder.typicode.com/todos/1.try...catch block to handle potential errors.