1. What is a Promise?
A Promise is an object that represents the eventual completion (or failure) of an asynchronous operation and its resulting value.
- States of a Promise:
- Pending – initial state, operation not finished yet.
 - Fulfilled (Resolved) – operation finished successfully.
 - Rejected – operation failed.
 
 
Think of a Promise as a “promise to deliver a result in the future”.
2. Creating a Promise
const myPromise = new Promise((resolve, reject) => {
    const success = true; // simulate operation
    if (success) {
        resolve("Operation successful!");
    } else {
        reject("Operation failed.");
    }
});
resolve(value)→ fulfills the promise.reject(error)→ rejects the promise.
3. Using Promises
.then() and .catch()
myPromise
    .then(result => {
        console.log(result); // "Operation successful!"
    })
    .catch(error => {
        console.error(error); // "Operation failed."
    });
.then()→ handles success..catch()→ handles errors..finally()→ runs regardless of success/failure:
myPromise.finally(() => console.log("Promise settled."));
4. Promises in Action
Example: simulate fetching data
function fetchData() {
    return new Promise((resolve, reject) => {
        setTimeout(() => {
            const data = { id: 1, name: "John" };
            resolve(data);
        }, 2000);
    });
}
fetchData()
    .then(data => console.log("Data received:", data))
    .catch(err => console.error("Error:", err));
- After 2 seconds, it logs the data.
 - If you replace 
resolve(data)withreject("Failed"), the.catch()handles it. 
5. Chaining Promises
You can chain .then() to run sequential asynchronous operations:
fetchData()
    .then(data => {
        console.log(data);
        return "Next step";
    })
    .then(msg => {
        console.log(msg);
    })
    .catch(err => console.error(err));
✅ Each .then() receives the return value of the previous .then().
6. Running Multiple Promises
Promise.all→ wait for all promises to finish (parallel execution):
const p1 = Promise.resolve(1);
const p2 = Promise.resolve(2);
const p3 = Promise.resolve(3);
Promise.all([p1, p2, p3]).then(values => console.log(values));
// Output: [1, 2, 3]
Promise.race→ resolves/rejects as soon as any promise finishes:
Promise.race([p1, p2, p3]).then(value => console.log(value));
// Output: 1 (first resolved)
7. Key Points
- Promises make async code more readable than nested callbacks (“callback hell”).
 - You can chain 
.then()calls to perform sequential async operations. .catch()handles errors,.finally()always executes.async/awaitis just syntactic sugar over Promises.
