From Callback Hell to Promise Paradise: Learn Callbacks, Promises, and Promise API in JavaScript

Photo by Joan Gamell on Unsplash

From Callback Hell to Promise Paradise: Learn Callbacks, Promises, and Promise API in JavaScript

To understand what is Promise API, you need to understand what are Promises in JavaScript before. If you don't know what are promises, bare with me, and I will explain them to you in simple words.

To understand Promises, you need to know what are callbacks.

Callbacks

Callback in simple terms is a function passed as an argument to another function. A basic syntax of a callback is as follows:

function display(sum){
    console.log(sum)
}

function add(num1, num2, callback){
    let sum = num1+num2;
    callback(sum)
}

add(2, 3, display)

A very basic use case of callbacks can be seen in functions: setTimeout() and setInterval().

setTimeout(()=>{console.log("Hello")}, 2000)
//Here the arrow function works as a callback

But, there was a major problem with callbacks, namely Pyramid of Doom, so to fix that Promises were introduced.

Pyramid Of Doom

Pyramid of Doom is a common programming problem in which if multiple aysnchronous events take place, then it would create a nested sequence of functions, that looks illegible and is not a good programming practice.

Pyramid Of Doom looks like this:

function loadScript(src, callback){
    let script = document.createElement('script')
    script.src = src
    script.onload = function(){
        callback(src, null)
    }
    script.onerror = function(){
        callback(new Error("zzz"))
    }
    document.body.appendChild(script)
}

//PYRAMID OF DOOM
loadScript("https://www.google.com", (src, error)=>{
    if(error){
        console.log('some error occured')
        return
    }
    loadScript("https://www.google.com", (src, error)=>{
        if(error){
            console.log('some error occured')
            return
        }

       loadScript("https://www.google.com", (src, error)=>{
        if(error){
            console.log('some error occured')
            return
        }
    })
})
})

Promises

Promises are used to handle asynchronous operations in Java. Basic syntax of a promise is as follows:

var promise = new Promise(function(resolve, reject){
    //some code
});

There are two functions that we use with promises, then and catch. They are used when a promise is either resolved or rejected. Basic syntax goes like this:

p1.then((value)=>{
    //some code
})

Here's an example Promise code for you to get a better insight:

let promise = new Promise(function(resolve, reject){
    console.log('Pending')
    setTimeout(()=>{
        console.log("Im'ma promise")
        resolve(true)
        // reject(new Error("some err occured"))
    }, 3000)
})

promise.then((value)=>{
    console.log(value)
}, promise.catch((err)=>{
    console.log(err)
}))

Promise API

Promise API is an API that provides 6 static functions. Let us look at them one by one.

  • Promise.resolve:

    You have already looked this before in basic Promise syntax. It creates a resolved promise.

  • Promise.reject:

    As the name says, it is used in case of some error, i.e., when the Promise gets rejected.

  • Promise.all:

    If you create multiple promises, and different times for their execution, they will execute according to their time. But, let's say that you want all the promises to give result at the same time, that's when you need Promise.all.

let p1=new Promise((resolve, reject)=>{
    setTimeout(() => {
        resolve(true)
    }, 2000);
})

let p2=new Promise((resolve, reject)=>{
    setTimeout(() => {
        resolve(true)
    }, 3000);
})

let p3=new Promise((resolve, reject)=>{
    setTimeout(() => {
        resolve(true)
    }, 4000);
})

let promise_all = Promise.all([p1, p2, p3])

promise_all.then((value)=>{
    console.log(value)
})
  • Promise.allSettled:

    If there is some promise, that rejects rather than resolving, then all won't run completely and break. Then, you need Promise.allSettled. It allows the code to run without any problem.

The following error occurs if we use Promise.all. image

  • Promise.race:

    As the name says, It's like a race. The promise that gets executed first gives result first. It is similar to Promise.all, but waits for only first settled promise. Also, when one promise gets rejected, rather than throwing error, the execution of code stops.

  • Promise.any:

    It is similar to Promise.race. But, here when all the promises get rejected an AggregateError object is thrown.

Here's what an AggregateError looks like: image

So, in short, callbacks are functions passed as arguments to another function. These help in asynchronous functionality but led to a major problem called Pyramid of Doom, so Promises were introduced. Then, we have Promise API, that provides various built in functions to make our job easy.

Did you find this article valuable?

Support Swapnil by becoming a sponsor. Any amount is appreciated!