🚀 What is a Promise?

  • A Promise is a special JavaScript object that represents the result of an asynchronous operation.
  • It’s like a placeholder for a value that will be available later (success or failure).

Think: “I promise I’ll give you the result later.”

📦 The 3 States of a Promise

  1. Pending – still waiting for the result.
  2. Fulfilled – completed successfully, has a value.
  3. Rejected – failed, has a reason (usually an error).

Once a promise is fulfilled or rejected, it’s settled and cannot change again.

🛠 How to Create a Promise

const myPromise = new Promise((resolve, reject) => { setTimeout(() => { resolve("Done! ✅"); // or reject("Something went wrong ❌"); }, 1000); }); 
  • The function inside new Promise runs immediately.
  • Call resolve(value) to fulfill.
  • Call reject(error) to fail.

⏳ Using a Promise

With .then and .catch

myPromise .then(result => console.log(result)) // "Done! ✅" .catch(err => console.error(err)); 

With async/await (sugar syntax)

async function run() { try { const result = await myPromise; console.log(result); // "Done! ✅" } catch (err) { console.error(err); } } 

⚡ Chaining Promises

You can chain .then calls to transform values step by step:

fetch("/data.json") .then(res => res.json()) .then(data => data.items) .then(items => console.log(items)) .catch(err => console.error(err)); 

Each .then returns a new Promise, which makes chaining possible.

🛑 Common Mistakes

  • Forgetting to return:
 .then(() => { doSomething(); }) // ❌ returns undefined .then(() => doSomething()) // ✅ returns the promise/value 
  • Mixing callbacks + promises unnecessarily.
  • Not handling errors: Always end with .catch or use try/catch.

🔄 Promise Utilities

  • Promise.all([p1, p2]) → waits for all to fulfill, fails fast if one rejects.
  • Promise.race([p1, p2]) → returns the first settled (fulfilled or rejected).
  • Promise.allSettled([p1, p2]) → waits for all, returns results with status.
  • Promise.any([p1, p2]) → first fulfilled, ignores rejections until all reject.

🔍 How Promises work under the hood

  • Resolvers (resolve/reject) queue their reactions as microtasks.
  • This means .then/catch callbacks always run after the current synchronous code, but before macrotasks like setTimeout.
console.log("Start"); Promise.resolve().then(() => console.log("Microtask")); setTimeout(() => console.log("Macrotask"), 0); console.log("End"); 

Output:

Start End Microtask Macrotask 

✅ Summary

  • A Promise is an object that represents future values.
  • Has 3 states: pending, fulfilled, rejected.
  • Use .then/.catch or async/await to consume.
  • Promises are scheduled as microtasks in the event loop, making them powerful for async flow control.

✨ Promises are the foundation of async/await and modern JavaScript concurrency.

Originally published on Bitlyst.