Synchronous programming executes tasks one after another. Each task must finish before the next one begins, which can block execution.
console.log("Start"); // Simulating a delay using a loop for (let i = 0; i < 1e9; i++) {} console.log("End");
Explanation: The loop blocks the rest of the code. "End" is printed after the loop finishes.
Output:
Asynchronous programming allows tasks to be executed independently, preventing blocking.
console.log("Start"); setTimeout(() => { console.log("This happens after 2 seconds"); }, 2000); console.log("End");
Explanation: setTimeout does not block execution, so "End" is printed before the message inside the setTimeout callback.
Output:
Callback functions are passed as arguments to other functions and are executed when the task is finished.
console.log("Start"); function fetchData(callback) { setTimeout(() => { callback("Data fetched!"); }, 2000); } fetchData((message) => { console.log(message); // This runs after 2 seconds }); console.log("End");
Explanation: fetchData accepts a callback and executes it after the simulated delay.
Output:
Promises represent the eventual completion (or failure) of an asynchronous operation.
console.log("Start"); const myPromise = new Promise((resolve, reject) => { const success = true; // Simulate success or failure setTimeout(() => { if (success) { resolve("Promise resolved!"); } else { reject("Promise rejected!"); } }, 2000); }); myPromise .then((message) => { console.log(message); // Runs when the promise is resolved }) .catch((message) => { console.log(message); // Runs if the promise is rejected }); console.log("End");
Explanation: The promise resolves after 2 seconds, triggering the .then()
method.
Output:
Multiple promises can be chained to handle sequential asynchronous tasks.
new Promise((resolve, reject) => { setTimeout(() => resolve("Step 1 complete"), 1000); }) .then((message) => { console.log(message); return new Promise((resolve) => setTimeout(() => resolve("Step 2 complete"), 1000)); }) .then((message) => { console.log(message); });
Explanation: Each promise resolves sequentially, logging "Step 1" and then "Step 2".
Output:
Promise.all() resolves when all promises in the array resolve.
const promise1 = new Promise((resolve) => setTimeout(() => resolve("First"), 1000)); const promise2 = new Promise((resolve) => setTimeout(() => resolve("Second"), 2000)); Promise.all([promise1, promise2]).then((results) => { console.log(results); // ["First", "Second"] });
Explanation: Promise.all() waits for all promises to resolve and returns their results.
Output:
Promise.race() resolves when the first promise in the array resolves.
const promise1 = new Promise((resolve) => setTimeout(() => resolve("First"), 2000)); const promise2 = new Promise((resolve) => setTimeout(() => resolve("Second"), 1000)); Promise.race([promise1, promise2]).then((result) => { console.log(result); // "Second" });
Explanation: Promise.race() resolves with the first promise that resolves.
Output:
Async/Await allows writing asynchronous code in a synchronous style.
console.log("Start"); async function fetchData() { const promise = new Promise((resolve) => setTimeout(() => resolve("Data fetched!"), 2000)); const result = await promise; // Pauses here until promise is resolved console.log(result); } fetchData(); console.log("End");
Explanation: The await
pauses the execution until the promise resolves, so "End" is printed before "Data fetched!".
Output:
Fetch API is used to make HTTP requests asynchronously.
fetch("https://jsonplaceholder.typicode.com/posts/1") .then((response) => response.json()) // Parse the JSON from the response .then((data) => { console.log(data); // Output the fetched data }) .catch((error) => { console.log("Error:", error); // Handle any errors });
Explanation: Fetches data from a placeholder API and logs the response.
Output: