DEV Community

Muhammad Rizwan Ashiq
Muhammad Rizwan Ashiq

Posted on

Promises

What is a Promise?

Promises are used to handle asynchronous operations introduced in ES6. It is an object that represents the eventual completion or failure of an asynchronous operation.

They are easy to manage when dealing with multiple asynchronous operations where callbacks can create callback hell leading to unmanageable code. Callback functions were used before promises, but they had limited functionality and resulted in unmanageable code. The nightmare that would result from having several callback functions would make the code unmanageable.

Create a Promise

A promise is created using the new keyword, and it takes a function as an argument. This function takes two parameters, resolve and reject. The resolve function is called when the asynchronous operation is successful, and the reject function is called when the asynchronous operation fails.

const promiseFunction = () => {
    new Promise((resolve, reject) => {
        // do something
        if (everythingIsOk) {
            resolve("success");
        } else {
            reject("failure");
        }
    });
};
Enter fullscreen mode Exit fullscreen mode

How to use a Promise?

A promise is used by calling the then() method on the promise object. The then() method takes two functions as arguments, the first function is called when the promise is resolved, and the second function is called when the promise is rejected.

promiseFunction()
    .then((result) => {
        // if everyThingIsOK, and promise is resolved, then this function is called
    })
    .catch((error) => {
        // if something went wrong, and promise is rejected, then this function is called
    });
Enter fullscreen mode Exit fullscreen mode

States of a Promise

A promise (in JS context) takes some time to execute. There are possible states of a promise:

  • fulfilled✅: Action related to the promise succeeded
  • rejected❌: Action related to the promise failed
  • pending⏳: Promise is still pending i.e. not fulfilled or rejected yet

As promise takes in two functions as parameters. That is, resolve and reject in declaring it.

Here is an example of a promise:

const myPromise = new Promise((resolve, reject) => { // resolve and reject are functions
  if (/* condition */) {
    resolve("Promise was fulfilled ✅");
  } else {
    reject("Promise was rejected ❌");
  }
});
Enter fullscreen mode Exit fullscreen mode

The resolve function is called when the promise is fulfilled and the reject function is called when the promise is rejected. The resolve and reject functions are called inside the promise. The resolve and reject functions are passed as parameters to the promise.

The then() method is used to handle the promise. It takes two functions as parameters. The first function is called when the promise is fulfilled ✅. The second function is called when the promise is rejected ❌.

myPromise
    // highlight-start
    .then((value) => {
        console.log(value);
    })
    // highlight-end
    .catch((error) => {
        console.log(error);
    });
Enter fullscreen mode Exit fullscreen mode

The catch() method is used to handle the promise when it is rejected ❌. It takes a function as a parameter. The function is called when the promise is rejected.

myPromise
    .then((value) => {
        console.log(value);
    })
    .catch((error) => {
        console.log(error);
    });
Enter fullscreen mode Exit fullscreen mode

Examples

Return a random number between 1 and 10

Let's create a promise that will return a random number between 1 and 10. If the number is greater than 5, the promise will be resolved, and if the number is less than 5, the promise will be rejected.

const randomNumberGenerator = () => {
    new Promise((resolve, reject) => {
        const randomNumber = Math.floor(Math.random() * 10) + 1;
        if (randomNumber > 5) {
            resolve(randomNumber);
        } else {
            reject(randomNumber);
        }
    });
};

randomNumberGenerator()
    .then((result) => {
        console.log(`Success: ${result}`);
    })
    .catch((error) => {
        console.log(`Error: ${error}`);
    });
Enter fullscreen mode Exit fullscreen mode

Fetching Data from an API using Promises

function getData() {
    return new Promise((resolve, reject) => {
        fetch("https://jsonplaceholder.typicode.com/todos/1")
            // Data will be assigned to the variable `response`, if the promise is fulfilled
            .then((response) => response.json())
            // ☝️ here we are converting the response to JSON, and returning it to the next `then` function
            .then((data) => resolve(data))
            // ☝️ here we are resolving the promise with the data
            .catch((error) => reject(error));
        // ☝️ here we are rejecting the promise with the error
    });
}

// Calling the function `getData`
getData()
    // 👇 `then()` will be called if the promise is resolved
    .then((data) => {
        console.log(data);
    })
    // 👇 `catch()` will be called if the promise is rejected
    .catch((error) => {
        console.log(error);
    });
Enter fullscreen mode Exit fullscreen mode

In the above example, getData() is a function that returns a promise. It fetches the data from the API. The then() method is used to handle the promise when it is fulfilled. The catch() method is used to handle the promise when it is rejected.

Promise Chaining

Promise chaining is a way to handle multiple promises. It is used to handle asynchronous operations in a better way. It is a replacement for callbacks and events. It is used to handle asynchronous operations in JavaScript, such as making HTTP requests to a server, reading from a file, or interacting with a database. They are easy to manage when dealing with multiple asynchronous operations where callbacks can create callback hell leading to unmanageable code. Callback functions were used before promises, but they had limited functionality and resulted in unmanageable code. The nightmare that would result from having several callback functions would make the code unmanageable.

const promise1 = Promise.resolve("Promise 1 resolved");
const promise2 = new Promise((resolve, reject) => {
    setTimeout(() => {
        resolve("Promise 2 resolved");
    }, 2000);
});

promise1
    .then((value) => {
        // `value` will be "Promise 1 resolved"
        console.log(value);
        return promise2; // returning the `promise2` to the next `then` function
    })
    .then((value) => {
        // `value` will be "Promise 2 resolved"
        console.log(value);
    })
    .catch((error) => {
        console.log(error);
    });
Enter fullscreen mode Exit fullscreen mode

In the above example, the promise1 is resolved first. Then the promise2 is resolved after 2 seconds. The then() method is used to handle the promise when it is fulfilled. The catch() method is used to handle the promise when it is rejected.

Promise.all()

It takes an array of promises as an argument. It returns a single promise. It resolves when all of the promises in the argument array have resolved. It rejects with the reason of the first promise that rejects.

const promise1 = Promise.resolve("Promise 1 resolved");
const promise2 = new Promise((resolve, reject) => {
    setTimeout(() => {
        resolve("Promise 2 resolved");
    }, 2000);
});

Promise.all([promise1, promise2])
    .then((values) => {
        console.log(values);
    })
    .catch((error) => {
        console.log(error);
    });
Enter fullscreen mode Exit fullscreen mode

Promise.allSettled()

It returns a promise that resolves after all of the given promises have either fulfilled or rejected, with an array of objects that each describes the outcome of each promise.

const promise1 = Promise.resolve("Promise 1 resolved");
const promise2 = new Promise((resolve, reject) => {
    setTimeout(() => {
        resolve("Promise 2 resolved");
    }, 2000);
});

Promise.allSettled([promise1, promise2])
    .then((values) => {
        console.log(values);
    })
    .catch((error) => {
        console.log(error);
    });
Enter fullscreen mode Exit fullscreen mode

Conclusion

Here we have learned about promises in JavaScript. We have learned about the Promise object, the then() method, the catch() method, promise chaining, Promise.all(), and Promise.allSettled(). We have also learned about the examples of promises in JavaScript.

Top comments (0)