Promises in JavaScript

From this article you will learn the following:

  • Promises in JavaScript what they are?
  • How to use them in an efficient way?

A promise is an object in JavaScript that returns a value which you hope to receive in the future not now. Its very well-suited for handling asynchronous operations.

Promise states: A promise has three states:

  • Pending: This is the initial state of promise. Async operation is still in process
  • Fulfilled: The task is done successfully and you can access the result using .then(data)
  • Rejected: An error happened and the task not completed. We can access the error using .catch(err)
  • Settled: This is the promise final state and it’s invoked after promise is resolved or rejected by using .finally()

Creating a promise using constructor

let state=true;
let promise = new Promise((resolve,reject)=>{
	if(state){
		//do some tasks here then resolve with result
		resolve("Task is done successfully")
	}else{
		//reject if any error appears and promise not completed
		reject("Task not completed");
	}
})

Promise accepted a function which it’s called executor which accepts two functions as a parameters resolve and reject
To see promise state and promise result create html file and inside this file include the following JavaScript code.

let state = true;
let promise = new Promise((resolve, reject) => {
  setTimeout(() => {
    if (state) {
      resolve("The task is done successfully");
    } else {
      reject("Task has an error and not completed");
    }
  }, 3 * 1000);
});
console.log(promise);

Based on state variable defined the promise state changes from pending to fulfilled or to rejected and this after 3 seconds the promise result will be The task is done successfully in case of fulfilled or Task has an error and not completed in case of rejection.

Note Once the promise reaches either fulfilled state or rejected state it’s stay in the state and can not switch. A promise cannot go from the fulfilled state to the rejected state and vice versa. Also cannot go back from the fulfilled state or rejected state to the pending state.

Consuming a promise: then , catch and finally

  • then() Method accepts a callback to be executed once the promise successfully executed (resolved).
  • catch() Method accepts a callback to be executed once the promise rejected.
  • finally() It will be executed after promise rejection or fulfilled.
let state = false;
let promise = new Promise((resolve, reject) => {
  setTimeout(() => {
    if (state) {
      resolve("The task is done successfully");
    } else {
      reject("Task has an error and not completed");
    }
  }, 3 * 1000);
});
promise
  .then((data) => {
    console.log(data);
  })
  .catch((err) => {
    console.log(err);
  })
  .finally(() => {
    console.log("This task executed once promise resolved or rejected ");
  });

Promise chaining

Promise chaining is a pattern that chains promises to execute asynchronous operations in sequence

const getNumOfUsers = () => {
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      resolve(10);
    }, 3000);
  });
};
getNumOfUsers()
  .then((result) => {
    console.log(result);
    return result * 2;
  })
  .then((data) => {
    console.log(data);
    return data * 3;
  })
  .then((data) => {
    console.log(data);
    return data * 4;
  })
  .then((data) => {
    console.log(data);
  });

  /*
   * The output will be
   * 10
   * 20
   * 60
   * 240
   */

Multiple handlers for one promise

When we calling .then multiple times on one promise without chaining it.

const getNumOfUsers = () => {
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      resolve(10);
    }, 3000);
  });
};
getNumOfUsers().then((result) => {
  console.log(result);
  return result * 2;
});
getNumOfUsers().then((data) => {
  console.log(data);
  return data * 3;
});
getNumOfUsers().then((data) => {
  console.log(data);
  return data * 4;
});
getNumOfUsers().then((data) => {
  console.log(data);
});
/*
 * The output will be
 * 10
 * 10
 * 10
 * 10
 */

All of promises are executed independently and do not pass the result to the next one. They do not have a relationship between them.
To make it chaining like before we will add a dependency between them like the following code each one receive the result from the previous one.

const getNumOfUsers = () => {
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      resolve(10);
    }, 3000);
  });
};
let firstCh = getNumOfUsers().then((result) => {
  console.log(result);
  return result * 2;
});
let secondCh = firstCh.then((data) => {
  console.log(data);
  return data * 3;
});
let thirdCh = secondCh.then((data) => {
  console.log(data);
  return data * 4;
});
let lastCh = thirdCh.then((data) => {
  console.log(data);
});
  /*
   * The output will be
   * 10
   * 20
   * 60
   * 240
   */

Subscribe to our Newsletter

Subscribe to tech-hour website to get all updates, new articles, new courses and projects. No spam ever. Unsubscribe at any time.