Welcome to another episode of "Gen Z JavaScript"! In this video, we're demystifying one of the most important concepts for modern web development: Promises. Learn what promises are, why we use them for asynchronous operations, and how to work with the .then(), .catch(), and .finally() methods. We'll break down this essential topic with a clear, easy-to-understand approach. Stay tuned for more videos on JavaScript, as well as Angular and React.js, as we build our skills together! 🔹 What is a Promise? A *Promise* is a special JavaScript object that represents the result of an **asynchronous operation**. It can be in one of three **states**: 1. *Pending* → initial state (neither fulfilled nor rejected). 2. *Fulfilled* → operation completed successfully → returns a value. 3. *Rejected* → operation failed → returns an error. --- 🔹 Why Promises? Before Promises, JavaScript developers used *callbacks* to handle async tasks (like fetching data from a server). But callbacks often led to *callback hell* (deep nesting, unreadable code): ```js doTask1(() =) { doTask2(() =) { doTask3(() =) { console.log("All tasks done"); }); }); }); ``` ✅ Promises flatten this into a cleaner chain. --- 🔹 Creating a Promise You create a Promise using the `new Promise()` constructor, which takes a function with two parameters: `resolve(value)` → called when the async operation succeeds. `reject(error)` → called when the async operation fails. Example: ```js const fetchData = new Promise((resolve, reject) =) { setTimeout(() =) { resolve("Data loaded"); // success // reject("Failed to load"); // uncomment for error }, 1000); }); ``` --- 🔹 Consuming a Promise You use `.then()` and `.catch()` to handle the result. ```js fetchData .then(data =) console.log(data)) // "Data loaded" .catch(err =) console.error(err)); // if rejected ``` --- 🔹 Promise Chaining One of the biggest advantages: you can **chain async tasks sequentially**. ```js fetchData .then(res =) res + " successfully") .then(msg =) msg + " 🎉") .then(finalMsg =) console.log(finalMsg)); // Output after 1 sec → "Data loaded successfully 🎉" ``` Each `.then()` returns a new Promise → making the chain possible. --- 🔹 Error Handling If something goes wrong, the error moves down the chain until caught: ```js fetchData .then(data =) { throw new Error("Something broke!"); }) .catch(err =) console.error("Caught:", err.message)); ``` --- 🔹 Real-world Example (API call simulation) ```js function getUser() { return new Promise((resolve, reject) =) { setTimeout(() =) resolve({ id: 1, name: "Alice" }), 1000); }); } function getOrders(userId) { return new Promise((resolve) =) { setTimeout(() =) resolve(["Order1", "Order2"]), 1000); }); } // Chaining getUser() .then(user =) { console.log("User:", user); return getOrders(user.id); }) .then(orders =) console.log("Orders:", orders)) .catch(err =) console.error(err)); ``` --- 🔹 Why Promises Matter *Avoid callback hell* cleaner, linear flow. *Error handling* easier with `.catch()`. *Foundation for async/await* `async/await` is just syntactic sugar on top of Promises, making code look synchronous. Example with `async/await`: