Everything you need to know about Promises

Everything you need to know about Promises

Promises in JavaScript

Β·

5 min read

βœ‹πŸ½ Introduction

Asynchronous programming is a common practice in JavaScript, as it allows for non-blocking code execution, improving the application's performance. However, handling asynchronous operations can be challenging, especially when dealing with multiple functions simultaneously. Promises are a powerful tool for handling asynchronous operations in JavaScript, simplifying the code and making it more readable, improving the performance of the application. In this article, we will discuss how Promises work and how developers can use them to handle asynchronous operations effectively. Let’s dive right into it πŸ˜‰

🀞🏽 What is a Promise?

A promise is an object that represents the eventual completion or failure of an asynchronous operation and its resulting value.

You can think of a promise in JavaScript as a Promise in real life. For instance, if you Promise to give someone money, that Promise will have two possible outcomes: completing (resolved) the Promise or failing (rejected) to complete the Promise.

Now that we know what a Promise is, let’s see how it works.

πŸ‘·πŸ½ How Promises work

A Promise can have three states: pending, resolved, or rejected. When a Promise is pending, it means the operation is still in progress. When a Promise is resolved, it means the operation was successful, and the resulting value is available. When a Promise is rejected, it means the operation failed, and the resulting error is available.

Example

Now that we know what Promises are and how they work. Let’s see an example for a better understanding. πŸ‘‡πŸ½


const ourPromise = new Promise((resolve, reject) => {
  // asynchronous operation
  if ( 2 + 2 == 4) {
    resolve('Success');
  } else {
    reject('Failed');
  }
});

In the example above, we created a Promise using the Promise constructor, which takes a function as an argument. This function is named ourPromise and serves as the executor function. It takes two arguments: resolve and reject. The resolve function is called when the operation is successful, and the resulting value is available. The reject function is called when the operation fails, and the resulting error is available.

So far we’ve only created the Promise but we need to interact with the Promise and we can do that by using two methods called .then() and .catch()

The .then() method is used to handle the resolved state of a Promise and the .catch() method is used to handle the rejected state of a Promise. Here is the other part of the same example above of using .then() and .catch():

ourPromise.then((result) => {
  console.log(result); // logs 'Resulting value'
})
.catch((error) => {
  console.error(error); // logs 'Error message'
});

Here is the full code πŸ‘‡πŸ½

const ourPromise = new Promise((resolve, reject) => {
  if (2 + 2 == 4) {
    resolve('Success');
  } else {
    reject('Failed');
  }
});

ourPromise
  .then((result) => {
    console.log(result); // logs 'Resulting value'
  })
  .catch((error) => {
    console.error(error); // logs 'Error message'
  });

πŸ‘¨πŸ½β€πŸ’» Using Promises in JavaScript

Promises can be used to handle any asynchronous operation, from fetching data from APIs to executing multiple operations simultaneously. Promises can be executed sequentially using Promise chaining or simultaneously using Promise.all() or Promise.race().

Fetching data from APIs

Promise chaining is basically a technique for executing a sequence of asynchronous operations. We can use the .then() method to chain multiple Promises together, where the resulting value of one Promise is passed as an argument to the next Promise. Here is an example of Promise chaining:

fetch('https://jsonplaceholder.typicode.com/users')
  .then(response => response.json())
  .then(data => console.log(data))
  .catch(error => console.error(error));

In the example above, the fetch() method returns a Promise that resolves with a Response object. We use the .json() method to extract the JSON body content from the Response object. The .json() method returns another Promise that resolves with the parsed JSON data. We then use .then() to log the data to the console. If any errors occur during this process, they will be caught by the .catch() method and logged to the console.

πŸ’‘PS: 99% of the time, You are going to see yourself using Promises to handle Fetch requests from an external API.

How to Use the Promise.all() method

Promise.all() can be used to execute multiple Promises simultaneously. The Promise.all() method takes an array of Promises as an argument and returns a Promise that resolves with an array of results when all Promises are resolved. Here is an example of using Promise.all() πŸ‘‡πŸ½

const promise1 = Promise.resolve('Promise 1');
const promise2 = Promise.resolve('Promise 2');
const promise3 = Promise.resolve('Promise 3');

Promise.all([promise1, promise2, promise3])
  .then(result => console.log(result)) // logs ['Promise 1', 'Promise 2', 'Promise 3']
  .catch(error => console.error(error));

From the example above, we created three Promises using Promise.resolve(). We then use Promise.all() to execute all three Promises simultaneously and wait for all Promises to resolve. The resulting value is an array of results from each Promise.

We can also use Promise.race() to execute a set of Promises and return the result of the first Promise that resolves. Here is an example of using Promise.race():

const promise1 = new Promise(resolve => setTimeout(resolve, 500, 'Promise 1'));
const promise2 = new Promise(resolve => setTimeout(resolve, 1000, 'Promise 2'));

Promise.race([promise1, promise2])
  .then(result => console.log(result)) // logs 'Promise 1'
  .catch(error => console.error(error));

In this example, we created two Promises using the Promise constructor and the setTimeout() function. The first Promise resolves after 500 milliseconds, and the second Promise resolves after 1000 milliseconds. We use Promise.race() to execute both Promises and return the result of the first Promise that resolves, which is 'Promise 1'.

Wrap Up

Promises are a powerful tool for handling asynchronous operations in JavaScript. They simplify the code and make it more readable, improving the performance of the application. Developers can use Promise.all(), Promise.race(), Promise.reject(), Promise.resolve(), .then(), .catch(), and Promise chaining to handle Promises effectively. Some of the advantages of Promises include improved code readability, avoiding callback hell, better error handling, and improved debugging capabilities. Promises are widely used in real-world applications and are essential in modern web development.

Conclusion

Congrats on getting to the end of this article πŸŽ‰. I hope you now understand the basics of how Promises works in JavaScript. See you next week and have a great weekend πŸ˜€

Β