DEV Community

Cover image for 🧠 JavaScript Promises Explained β€” A Complete Guide for Beginners
Lokesh Keswani
Lokesh Keswani

Posted on

🧠 JavaScript Promises Explained β€” A Complete Guide for Beginners

"I don't get Promises" β€” Every beginner at least once.

This is your ultimate guide to understanding JavaScript Promises from scratch, with real-life analogies, live examples, and step-by-step breakdowns.


πŸ• Real-Life Analogy: Ordering Pizza

Imagine this:

  • You order a pizza πŸ•.
  • The restaurant says: "We'll deliver it in 30 minutes." GIF via Giphy
  • You're now waiting β€” this is like an asynchronous task.
  • When the pizza arrives, you eat = βœ…_ Success_
  • If they mess up, no pizza = ❌ Failure

JavaScript Promises work just like that. You're not blocking your whole evening waiting β€” you can keep watching your show while the delivery happens in the background.


πŸ€” What Is a Promise?

GIF via Giphy
A Promise is a JavaScript object that represents an action that hasn’t finished yet but will finish in the future. It can result in:

  • Resolved (success)
  • Rejected (failure)
  • Pending (still waiting)

Why Promises?

Traditionally, we handled async actions with callbacks. But callbacks quickly become hard to manage, especially if you have to chain multiple async actions.

Promises help you:

  • Write cleaner code
  • Chain operations easily
  • Handle errors in one place

Basic Syntax:

let promise = new Promise(function(resolve, reject) {
  // async task
});
Enter fullscreen mode Exit fullscreen mode

resolve() means success, reject() means failure.


πŸ“¦ Example 1: Creating Your First Promise

GIF via Giphy

let pizzaOrder = new Promise(function(resolve, reject) {
  let pizzaReady = true; // Try changing this to false

  if (pizzaReady) {
    resolve("Your pizza is here!");
  } else {
    reject("Sorry, pizza shop is closed.");
  }
});
Enter fullscreen mode Exit fullscreen mode

You now have a Promise object. But how do you use it?

Using .then() and .catch():

pizzaOrder
  .then(function(result) {
    console.log("Success:", result);
  })
  .catch(function(error) {
    console.log("Error:", error);
  });
Enter fullscreen mode Exit fullscreen mode

πŸ” .then() β€” Handling Success

.then() is a method that runs when a Promise is resolved. Think of it as "what to do next if things go right."

promise.then((value) => {
  console.log("Resolved with:", value);
});
Enter fullscreen mode Exit fullscreen mode
  • It takes one argument: a callback function
  • That function receives the result of resolve()

πŸ”₯ .catch() β€” Handling Errors

.catch() is a method that runs when a Promise is rejected. It's like a dedicated error handler.

promise.catch((error) => {
  console.error("Something went wrong:", error);
});
Enter fullscreen mode Exit fullscreen mode
  • Helps prevent your app from crashing
  • Use it at the end of your chain to capture any error from the previous steps

βœ…

.finally() β€” Always Runs

.finally() runs whether the promise is resolved or rejected.

promise.finally(() => {
  console.log("Cleanup, logging, or UI update.");
});
Enter fullscreen mode Exit fullscreen mode
  • Great for hiding loaders, resetting UI, logging
  • Doesn’t receive any arguments

Full Flow Example:

pizzaOrder
  .then((res) => console.log("βœ”", res))
  .catch((err) => console.log("βœ–", err))
  .finally(() => console.log("πŸ“¦ Order attempt finished"));
Enter fullscreen mode Exit fullscreen mode

Live Example: Try it on JSFiddle - Basic Pizza Promise or paste into browser console.


🧍️ How Promises Work Internally

NEW Promise
   |
   V
Pending  ---> Resolved (Success)
       \---> Rejected (Failure)
Enter fullscreen mode Exit fullscreen mode

The Promise only resolves ONCE. Either resolve OR reject.


🧩 States of a Promise

State Description
Pending Waiting for result (default state)
Fulfilled Operation completed successfully
Rejected Operation failed

πŸ”€ Example 2: Chaining Promises

GIF via Giphy

function stepOne() {
  return new Promise((resolve) => {
    setTimeout(() => resolve("Step 1 done"), 1000);
  });
}

function stepTwo() {
  return new Promise((resolve) => {
    setTimeout(() => resolve("Step 2 done"), 1000);
  });
}

stepOne()
  .then((msg) => {
    console.log(msg);
    return stepTwo();
  })
  .then((msg) => {
    console.log(msg);
  })
  .finally(() => {
    console.log("All steps finished.");
  });
Enter fullscreen mode Exit fullscreen mode

Why Chaining Is Important:

Without chaining, each .then() would run independently. With chaining, you ensure they run in sequence.

Live Example: Try it on JSFiddle - Promise Chaining


⚠️ Common Beginner Mistakes

GIF via Giphy

1. Not returning a Promise inside .then()

.then(() => {
  stepTwo(); // Not returned β€” won't wait for this
})
Enter fullscreen mode Exit fullscreen mode

Correct:

.then(() => {
  return stepTwo();
})
Enter fullscreen mode Exit fullscreen mode

2. Handling success only and ignoring errors

Always use .catch() to handle errors, or your app may crash silently.

3. Nested Promises (Anti-pattern)

stepOne().then(() => {
  stepTwo().then(() => {
    console.log("Done");
  });
});
Enter fullscreen mode Exit fullscreen mode

Better:

stepOne()
  .then(() => stepTwo())
  .then(() => console.log("Done"));
Enter fullscreen mode Exit fullscreen mode

✨ Async/Await β€” Clean Alternative to Promises

With async/await, you can write asynchronous code that looks like synchronous code.

async function makePizza() {
  try {
    let msg1 = await stepOne();
    console.log(msg1);

    let msg2 = await stepTwo();
    console.log(msg2);
  } catch (error) {
    console.log("Error:", error);
  }
}

makePizza();
Enter fullscreen mode Exit fullscreen mode

await waits for the promise to resolve. You can only use await inside async functions.

Live Example: Try it on JSFiddle - Async/Await


πŸ“± Real API Call with Fetch + Promises

GIF via Giphy
Let's now look at how Promises power real-world API calls with fetch().

Using .then() Chain:

fetch("https://jsonplaceholder.typicode.com/users/1")
  .then((response) => response.json())
  .then((user) => console.log(user))
  .catch((error) => console.error("Error fetching:", error))
  .finally(() => console.log("Request completed"));
Enter fullscreen mode Exit fullscreen mode

Using async/await:

async function getUser() {
  try {
    const response = await fetch("https://jsonplaceholder.typicode.com/users/1");
    const user = await response.json();
    console.log(user);
  } catch (error) {
    console.log("Error:", error);
  } finally {
    console.log("Request completed");
  }
}

getUser();
Enter fullscreen mode Exit fullscreen mode

πŸ§ͺ What’s Happening:

  • The fetch call returns a Promise.
  • If resolved, .then() gives you a Response object.
  • .json() is another Promise to convert the stream into usable data.
  • Any network or conversion failure goes to .catch().

🎯 Practice Challenge

GIF via Giphy
Challenge: Write a function using async/await that:

  • Fetches posts from https://jsonplaceholder.typicode.com/posts
  • Logs the first 5 post titles

Solution:

async function getPosts() {
  try {
    const res = await fetch("https://jsonplaceholder.typicode.com/posts");
    const posts = await res.json();
    posts.slice(0, 5).forEach(post => console.log(post.title));
  } catch (e) {
    console.error("Error:", e);
  } finally {
    console.log("Finished fetching posts");
  }
}

getPosts();
Enter fullscreen mode Exit fullscreen mode

Feel free to customize it, chain multiple fetches, or try .then() instead of async/await to test your understanding.


🧠 Final Thoughts

JavaScript Promises are one of the most powerful tools for handling asynchronous operations. Mastering them unlocks the ability to work with APIs, animations, timers, and all async logic like a pro.

Key Takeaways:

Promises have 3 states: Pending β†’ Fulfilled or Rejected

  • .then() is for success, .catch() is for errors
  • .finally() always runs
  • Use async/await for cleaner syntax

βœ… Next Steps:

  • Build a fake food ordering app using chained Promises
  • Refactor old callback-based code to Promises
  • Explore Promise.all() and Promise.race() If this helped you understand Promises better, please ❀️ the post, drop a comment, or follow me for more beginner-friendly JavaScript tutorials! GIF via Giphy
    Author: Lokesh Keswani

Follow me on Dev.to for more dev content.

Top comments (0)