Skip to main content

Command Palette

Search for a command to run...

Promises in JavaScript Explained in a Simple Way

Updated
3 min read

Introduction

When you start working with asynchronous code in JavaScript, things can quickly become confusing. Tasks like fetching data, reading files, or waiting for a timer do not happen instantly.

Earlier, developers used callbacks to handle these situations. But callbacks often made the code messy and hard to manage.

Promises were introduced to solve this problem. They make asynchronous code easier to read, write, and understand.


What Problem Promises Solve

Before promises, callbacks were commonly used.

Example with Callbacks

setTimeout(() => {
  console.log("Step 1");
  setTimeout(() => {
    console.log("Step 2");
    setTimeout(() => {
      console.log("Step 3");
    }, 1000);
  }, 1000);
}, 1000);

Problems

• Code becomes deeply nested • Hard to read and understand • Difficult to handle errors • Known as callback hell


What is a Promise

A Promise is like a promise in real life. It represents a value that will be available in the future.

Think of it like ordering food online:

• You place an order • It is being prepared • It is either delivered or cancelled

In JavaScript, a promise follows the same idea.


Promise States

A promise has three states:

Pending

• Initial state • The task is still running

Fulfilled

• The task completed successfully • You get the result

Rejected

• The task failed • You get an error


Basic Promise Lifecycle

Creating a Promise

const promise = new Promise((resolve, reject) => {
  let success = true;

  if (success) {
    resolve("Task completed");
  } else {
    reject("Task failed");
  }
});

Handling the Result

promise
  .then((result) => {
    console.log(result);
  })
  .catch((error) => {
    console.log(error);
  });

Handling Success and Failure

then for success

promise.then((data) => {
  console.log(data);
});

catch for errors

promise.catch((error) => {
  console.log(error);
});

finally runs always

promise.finally(() => {
  console.log("Done");
});

Promise Chaining Concept

One of the biggest advantages of promises is chaining. You can perform multiple asynchronous tasks step by step.

Example

const promise = new Promise((resolve) => {
  resolve(2);
});

promise
  .then((num) => {
    console.log(num);
    return num * 2;
  })
  .then((num) => {
    console.log(num);
    return num * 2;
  })
  .then((num) => {
    console.log(num);
  });

Why chaining is useful

• Avoids nested code • Makes flow clear and readable • Easier error handling


Promises vs Callbacks

Callbacks

• Lead to nested structure • Hard to manage • Error handling is messy

Promises

• Cleaner and structured • Easy to chain • Better error handling


Real Life Thinking

Promise means future value.

You do not have the result right now, but you know:

• It will come later • It may succeed • It may fail

This makes your code more predictable.


Why Promises Improve Readability

• Code looks flat instead of nested • Clear separation of success and failure • Easier to follow the flow


Conclusion

Promises are one of the most important concepts in JavaScript. They solve the problems of callbacks and make asynchronous code much easier to handle.

Once you understand promises, you will be able to write cleaner and more professional code. They are also the foundation for modern features like async and await, which you will learn next.