Promises in Javascript
Tags: javascript, beginners, promises, codeofaccuracy
Published: 2023-04-17 06:39:17

In JavaScript, a Promise is a built-in object that represents the eventual completion (or failure) of an asynchronous operation, and its resulting value. It provides a cleaner and more organized way to handle asynchronous code, avoiding the infamous `callback hell`.

Here's an example of how to use `Promises` in JavaScript:

```
const getData = () => {
  return new Promise((resolve, reject) => {
    // Perform an asynchronous operation, such as fetching data from an API Currently we are taking static data for example.
    const data = { id: 1, name: "Sam Adam" };
    if (data) {
      // If the operation is successful, call the "resolve" method with the data
      resolve(data);
    } else {
      // If there's an error, call the "reject" method with the error message
      reject("Error: Unable to retrieve data.");
    }
  });
};

// Call the Promise function and handle the response using "then" and "catch" methods
getData()
  .then((data) => {
    console.log("Data retrieved successfully:", data);
  })
  .catch((error) => {
    console.error("Error occurred while retrieving data:", error);
  });
```

In the example above, the `getData()` function returns a Promise object, which performs an `asynchronous` operation of fetching data from an API. If the operation is successful, the Promise calls the `resolve()` method with the data, and if there's an error, it calls the `reject()` method with the error message.

To handle the response from the Promise, you can use the `then()` and `catch()` methods. The `then()` method is called when the Promise is resolved successfully, and it receives the data as a parameter. The `catch()` method is called when the Promise is rejected with an error, and it receives the error message as a parameter.

**Chaining Promises**

```
const getData = () => {
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      const data = { id: 1, name: "John Doe" };
      if (data) {
        resolve(data);
      } else {
        reject(new Error("Unable to retrieve data."));
      }
    }, 2000);
  });
};

const getDetails = (data) => {
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      const details = { age: 30, city: "New York" };
      if (details) {
        resolve({ ...data, ...details });
      } else {
        reject(new Error("Unable to retrieve details."));
      }
    }, 2000);
  });
};

getData()
  .then(getDetails)
  .then((result) => {
    console.log(result); // Output: { id: 1, name: "John Doe", age: 30, city: "New York" }
  })
  .catch((error) => {
    console.error(error);
  });
```

In the example above, we have two Promises, `getData()` and `getDetails()`, that simulate fetching data from an API. The `getDetails()` Promise depends on the data returned by the `getData()` Promise. We use the `then()` method to chain these Promises together. The `then()` method takes a callback function that returns another Promise. The value returned by the first Promise is passed as an argument to the callback function of the second Promise. This process can be repeated as many times as necessary.

We use the `getData()` Promise to retrieve some data, and then chain the `getDetails()` Promise to retrieve additional details about that data. Finally, we use the `then()` method to log the result of both Promises chained together.

**Promise.all()**

The `Promise.all()` method allows you to run multiple Promises in parallel and wait for all of them to complete. This method takes an array of Promises as its argument and returns a new Promise that is fulfilled when all of the Promises in the array have been fulfilled.

```
const promise1 = new Promise((resolve) => setTimeout(resolve, 2000, "foo"));
const promise2 = 10;
const promise3 = new Promise((resolve) =>
  setTimeout(resolve, 3000, "bar")
);

Promise.all([promise1, promise2, promise3]).then((values) =>
  console.log(values)
);
// Output: ["foo", 10, "bar"]
```

In the example above, we create three Promises and pass them to the `Promise.all()` method. The `then()` method is used to log the array of values returned by the Promises when they are all fulfilled.

**Promise.race()**

The `Promise.race()` method allows you to run multiple Promises in parallel and return the value of the first Promise that is fulfilled.

```
const promise1 = new Promise((resolve) => setTimeout(resolve, 2000, "foo"));
const promise2 = new Promise((resolve) =>
  setTimeout(resolve, 3000, "bar")
);

Promise.race([promise1, promise2]).then((value) => console.log(value));
// Output: "foo"
```

In the example above, we create two Promises and pass them to the `Promise.race()` method. The `then()` method is used to log the value of the first Promise that is fulfilled. In this case, `promise1` is fulfilled first, so its value ("foo") is logged.

**Promise.allSettled()**

 `Promise.allSettled()` was introduced in ES2020. It takes an array of Promises as its input and returns a new Promise that resolves to an array of objects, one for each Promise in the input array. Each object in the resulting array represents the state of the corresponding Promise and contains two properties:

**status:** The status of the Promise. It can be either "fulfilled" or "rejected".

**value or reason:** Depending on whether the Promise was fulfilled or rejected, this property contains either the fulfilled value or the rejection reason.

Here's an example of how Promise.allSettled() works:

```
const promises = [
  Promise.resolve("resolved"),
  Promise.reject("rejected"),
  Promise.resolve("resolved again"),
];

Promise.allSettled(promises).then((results) => console.log(results));
// Output: [
//   { status: "fulfilled", value: "resolved" },
//   { status: "rejected", reason: "rejected" },
//   { status: "fulfilled", value: "resolved again" }
// ]
```

In this example, we create an array of three Promises. The first and third Promises are fulfilled with the values "resolved" and "resolved again", respectively. The second Promise is rejected with the reason "rejected". We then pass this array of Promises to `Promise.allSettled()`, which returns a new Promise that resolves to an array of three objects representing the state of each Promise. The `then()` method is used to log the resulting array of objects to the console.

Note that unlike `Promise.all()`, `Promise.allSettled()` waits for all Promises to settle (i.e., either fulfill or reject), regardless of their outcome. This means that even if some of the Promises are rejected, the resulting Promise returned by `Promise.allSettled()` will still resolve with an array of objects representing the state of all the Promises.

**Repl as Example :** [https://replit.com/@CodeOf1/PromisesAPI](https://replit.com/@CodeOf1/PromisesAPI)

`Summary`
Promises are a powerful tool in JavaScript for working with asynchronous code. They allow you to handle the success and failure of asynchronous operations in a more structured and readable way. In addition to the `then()` and `catch()` methods, you can also chain Promises together with the `then()` method, and run multiple Promises in parallel with the `Promise.all()` and `Promise.race()` methods.