JavaScript Promises

Hi Guys, Welcome to Proto Coders Point. In this article, we’ll learn about JavaScript Promises!

JavaScript is synchronous [single threaded] language.

While executing the code JavaScript runs from top to bottom, line by line so it is synchronous but we can change the behavior of JavaScript to asynchronous using some functions.

Why Promises?

Writing functions inside another function as an argument is known as callbacks. We use callbacks for breaking the tasks into small tasks but as we use callbacks a lot it turns into a callback hell.

So what’s the solution to this hell? – Promises – they are used to solve the callback hell problems and to handle our tasks in a better way.

Understanding Promises in javascript!

Syntax – Basic JS promises code

var promise = new Promise(function(resolve, reject) {
  const x = "ProtoCodersPoint";
  const y = "ProtoCodersPoint"
  if(x === y) {
    resolve();
  } else {
    reject();
  }
});
   
promise.
    then(function () {
        console.log('Success, You are a Coders');
    }).
    catch(function () {
        console.log('Some error has occurred');
    });

There are three kinds of Promises – Pending, Resolve and Reject, For eg – We have a pizza shop. According to that:-

  • Pending: The situation when customer is taking time to place an order of pizza, it’s pending
  • Resolve: The situation when customer has received pizza and he is happy
  • Reject: The situation when customer didn’t receive his order and left

.Then Handler

Use .then handler – It returns a promise when our actual promise was resolved.

.then(() => {})

You’re telling someone to first do this, then do this.

Promise Chaining

You keep writing .then(() => {}) and code does the tasks, one after the another. It is much effective than callback.

.then(() => {
    console.log("Pizza was ordered") 
})

.then(() => {
    console.log("Production has started") 
})

.then(() => {
    console.log("Pizza was delivered") 
})

Promises: Error Handling

Let’s catch our error. Suppose our Pizza Store is closed. So we’ll say

let storeOpen = false;

To Handle this, we use the .catch handler

Just like .then handler, it also returns a promise only when our actual promise is rejected.

Note: Make sure you have no code between your previous .then handler and .catch handler

.catch(() => {
  console.log("Customer Left")
})

.Finally Handler

It works when our promise is resolved or rejected, regardless of anything.

.finally(() => { 
    console.log("end of the day")
})

.then works when the promise is resolved.

.catch works when the promise is rejected.

.finally works when the promise is resolved or rejected

Now, We’ll look at how we can write promises in a better way to keep our code simple and clean using async & await.

Before:

function order(){
   return new Promise((resolve, reject) => {
 // Write code here})
}

After: using async/await

Just write the word async before any normal function & it becomes a promise.

async function order(){ // Write code here }

Try and Catch

try word is used to run our code

catch is used to catch our errors

Promises -> resolve, reject

Async/Await -> try, catch

async function kitchen(){
   try {
     await abc;
   } catch(error) {
     console.log("abc does not exist",error)
}
kitchen()  // run the code

Now, What is Await?

Await Keyword means waiting until the promise returns its result & settles.

Example:

We want to ask our customer which toppings would they love to have on their pizza?

So, the kitchen is stopped but another staff is working outside.

async function kitchen(){
 console.log("A Pizza")
 console.log("B Pizza")
 console.log("C Pizza")
 
 await toppings_choice()
 console.log("Chilli Flakes")
 console.log("Cheese")
}
// Trigger the function
kitchen();

console.log("Staff working outside")

We’re asking customers & till then, other works are done.

Once, we get the toppings chosen by the customer, we can enter the kitchen and finish the job.

While using Async/ Await, you can also use .then, .catch, .finally handlers because they also are a core part of promises.

All you need to know about Promise.all

Promise.all take asynchronous functions to the new level as it helps you in a grouping of promises.

The Promise.all() method accepts an emphasized object, such as an array of promises as a value, and returns a single promise that resolves to a resulting array of the input promises.

When all input promises have been resolved or the emphasized value does not contain a promise, the returned promise will be resolved.

It rejects straight away when a value promise rejects.

Where it is used?

It is mostly used when there are many asynchronous tasks happening that the overall code depends upon to work successfully – all the code that we want to run before we continue to execute the code.

const firstpromise = new Promise((resolve, reject) => {
  setTimeout(resolve, 200, "first promise resolved");
}); //will be resolved after 200ms

const secondpromise = 38; //non-promise

const thirdpromise = new Promise((resolve, reject) => {
  setTimeout(resolve, 100, "second promise resolved");
}); // will be resolved after 100ms

Promise.all([firstpromise, secondpromise, thirdpromise])
  .then((values) => {
    console.log(values);
  })
  .catch((err) => {
    console.log(err);
});

//expected output: ['first promise resolved', 38, 'second promise resolved']

 If any of the promises fail or rejects, then all the remaining promises also fail. Then Promise.all get rejected.

Promise.allSettled()

Promise.allSettled() is much useful for performing independent async functions, and collecting the result of those operations.

It accepts a list of Promises and returns a new Promise that resolves after all the input Promises have been settled, resolved, or rejected.

JavaScript Promise.allSettled() example below:

var arr=[];

Promise.allSettled([A(),B(),C(),D()])
  .then((value)=>{
      for(var i of value){
          if(i.status=='fulfilled'){
            arr.push(i.value)
          }
          
      }
    
    console.log(arr);
}).catch(console.log);

function A(){
    return new Promise((resolve,reject)=>{
        resolve("A Solved"); 
    });  
}

function B(){
    return new Promise((resolve,reject)=>{
        resolve("B Solved");
   });  
}

function C(){
    return new Promise((resolve,reject)=>{
        resolve("C Solved");
   });  
}

function D(){
    return new Promise((resolve,reject)=>{
        reject("D Rejected");
   });  
}

The promise returned by Promise.allSettled()  fulfills an array, doesn’t matter if few or all input promises are rejected.

So this was all about understanding JavaScript Promises. Links to more resources for understanding this visually!

Is JavaScript Synchronous or Asynchronous?

What the Heck is a callback?

Understanding Promises in JavaScript – Part 1

Understanding Promises in JavaScript – Part 2

The Better way to write promises in JavaScript

I hope you liked this article. If you did, please like and share it.