Skip to main content

Command Palette

Search for a command to run...

Promises in JavaScript

Updated
7 min read
Promises in JavaScript

Modern JavaScript applications perform many tasks that take time.

Examples:

  • Fetching data from APIs

  • Reading databases

  • Uploading files

  • Authentication systems

  • Waiting for timers

These operations are asynchronous.

Before promises, developers mainly used callbacks to handle asynchronous tasks.

But callbacks created many problems like:

  • Nested code

  • Difficult debugging

  • Poor readability

To solve these problems, JavaScript introduced Promises.

In this blog, we will learn:

  • What problem promises solve

  • Promise states

  • Promise lifecycle

  • Handling success and failure

  • Promise chaining

  • Internal working of promises

Everything will be explained from basic to advanced in easy language.


What is a Promise?

A Promise is an object that represents:

A future value or future result of an asynchronous operation.

This means:

The value is not available immediately.

It may come later.


Real Life Example

Imagine ordering food online.

When you place the order:

  • Food is not delivered instantly

  • Restaurant prepares the food

  • Delivery arrives later

The food delivery behaves like a promise.

You trust that:

  • Either food will arrive

  • Or the order will fail

This is exactly how promises work.


Why Promises Were Introduced

Before promises, callbacks were used.

Example:

loginUser(() => {

   getProfile(() => {

      getPosts(() => {

         getComments(() => {

         });

      });

   });

});

This creates deeply nested code.

This problem is called:

Callback Hell

Problems with callback hell:

  • Hard to read

  • Difficult to debug

  • Difficult maintenance

  • Pyramid-shaped code


Promises Solve These Problems

Promises improve:

  • Readability

  • Error handling

  • Code structure

  • Async flow management


Promise Syntax

const promise = new Promise((resolve, reject) => {

});

A promise constructor takes a callback function with two parameters:

  • resolve

  • reject


Promise States

A promise has three states.


1. Pending

Initial state.

The operation is still running.


2. Fulfilled

The operation completed successfully.


3. Rejected

The operation failed.


Promise Lifecycle Diagram

             Promise Created
                    │
                    ▼
                Pending
               /       \
              /         \
             ▼         ▼
       Fulfilled      Rejected

Basic Promise Example

const promise = new Promise((resolve, reject) => {

   let success = true;

   if(success) {
      resolve("Data Loaded");
   } else {
      reject("Error Loading Data");
   }

});

Handling Promise Success

The .then() method handles successful promises.


Example

const promise = new Promise((resolve, reject) => {

   resolve("Promise Resolved");

});

promise.then((result) => {

   console.log(result);

});

Output

Promise Resolved

Handling Promise Failure

The .catch() method handles rejected promises.


Example

const promise = new Promise((resolve, reject) => {

   reject("Something Went Wrong");

});

promise.catch((error) => {

   console.log(error);

});

Output

Something Went Wrong

Handling Both Success and Failure

const promise = new Promise((resolve, reject) => {

   let success = false;

   if(success) {
      resolve("Success");
   } else {
      reject("Failure");
   }

});

promise
.then((data) => {

   console.log(data);

})
.catch((error) => {

   console.log(error);

});

Output

Failure

How Promises Work Internally

Step-by-step:

  1. Promise starts in pending state

  2. Async operation runs

  3. If successful → resolve()

  4. If failed → reject()

  5. .then() handles success

  6. .catch() handles errors


Promise Execution Flow

Promise Created
       │
       ▼
Async Task Starts
       │
       ▼
Pending State
       │
 ┌─────┴─────┐
 ▼           ▼
resolve()   reject()
 ▼           ▼
.then()    .catch()

Promise Example with setTimeout

const promise = new Promise((resolve, reject) => {

   setTimeout(() => {

      resolve("Data Received After 2 Seconds");

   }, 2000);

});

promise.then((data) => {

   console.log(data);

});

Output

Data Received After 2 Seconds

Promises Represent Future Values

When promise is created:

const data = fetch("api-url");

The actual response is not available immediately.

The promise says:

"I will provide the value later."


Promise Chaining

Promises can be chained using multiple .then() methods.


Example

Promise.resolve(5)

.then((num) => {

   return num * 2;

})

.then((result) => {

   return result + 10;

})

.then((finalResult) => {

   console.log(finalResult);

});

Output

20

How Chaining Works

Start Value = 5
      │
      ▼
Multiply by 2
      │
      ▼
10
      │
      ▼
Add 10
      │
      ▼
20

Why Promise Chaining is Useful

Without chaining:

  • Nested callbacks increase

  • Code becomes messy

With chaining:

  • Cleaner flow

  • Better readability

  • Easier debugging


Callback vs Promise Comparison


Callback Style

loginUser(() => {

   getProfile(() => {

      getPosts(() => {

      });

   });

});

Problems:

  • Deep nesting

  • Hard readability

  • Difficult maintenance


Promise Style

loginUser()
.then(() => getProfile())
.then(() => getPosts())
.catch(err => console.log(err));

Benefits:

  • Flat structure

  • Cleaner code

  • Better error handling


Visual Comparison Diagram

Callbacks:

Task
 └── Task
      └── Task
           └── Task


Promises:

Task
  │
  ▼
.then()
  │
  ▼
.then()
  │
  ▼
.catch()

Promise.catch()

.catch() handles all previous errors in chain.


Example

Promise.resolve("Start")

.then((data) => {

   throw new Error("Something Failed");

})

.catch((error) => {

   console.log(error.message);

});

Output

Something Failed

Promise.finally()

finally() executes no matter what happens.


Example

Promise.resolve("Done")

.finally(() => {

   console.log("Cleanup Completed");

});

Output

Cleanup Completed

Real World API Example

fetch("https://jsonplaceholder.typicode.com/users")

.then((response) => {

   return response.json();

})

.then((data) => {

   console.log(data);

})

.catch((error) => {

   console.log(error);

});

This is how promises are commonly used in APIs.


Promise Methods

Method Purpose
.then() Handles success
.catch() Handles errors
.finally() Runs always

Advanced Promise Methods

JavaScript also provides:

  • Promise.all()

  • Promise.race()

  • Promise.any()

  • Promise.allSettled()

These help manage multiple promises together.


Promise.all

Example

const p1 = Promise.resolve("A");
const p2 = Promise.resolve("B");

Promise.all([p1, p2])

.then((result) => {

   console.log(result);

});

Output

[ 'A', 'B' ]

Benefits of Promises

Benefit Explanation
Better readability Cleaner async code
Avoid callback hell Flat structure
Better error handling Centralized catch
Chaining support Organized execution
Future value handling Works with async operations

Common Mistakes


1. Forgetting Return in Chaining

Wrong:

.then((data) => {

   data * 2;

})

Correct:

.then((data) => {

   return data * 2;

})

2. Not Handling Errors

Wrong:

fetchData().then(data => console.log(data));

Correct:

fetchData()
.then(data => console.log(data))
.catch(err => console.log(err));

Internal Architecture of Promises

Promise Created
       │
       ▼
Pending State
       │
       ▼
Event Loop Monitors
       │
 ┌─────┴─────┐
 ▼           ▼
Resolved   Rejected
 ▼           ▼
.then()    .catch()

Promises vs Async/Await

Promises are powerful.

But async/await makes promise-based code even cleaner.

Async/await is actually built on top of promises.


Conclusion

Promises are one of the most important concepts in JavaScript.

They solved major problems created by callbacks and made asynchronous programming cleaner and easier.

Promises help developers:

  • Manage async tasks properly

  • Handle errors efficiently

  • Write readable code

  • Avoid callback hell

Modern JavaScript development heavily depends on promises, and understanding them is essential before learning async/await.

Thank you for reading this blog.

I hope this helped you understand promises in JavaScript from basic to advanced concepts in a simple and practical way.

Your feedback is always appreciated.

If you found this blog useful, feel free to share your thoughts and suggestions for future topics.

1 views