In JavaScript, we often need to accomplish time-consuming tasks such as retrieving information from a database or running some computations. These are called asynchronous operations, because they do not complete immediately and require some time before they are finished.

A Promise enables the tasks to be carried out in an orderly and easier manner. It stands for a value which will be available in due course even though it is not currently available.

When should we use Promises and why are they useful?

In the absence of promises, we used to have callbacks for all the asynchronous tasks, which could become complicated easily. With Promises, we are able to prevent this mishap and hassle, simplifying our work and making the code structured.

In what way does a Promise work?

Consider the following example.
Assume that you need to perform three tasks: walk your dog, clean the kitchen, and take out the trash. Each of these tasks promises to either successfully complete or fail.

function walkDog() {
  return new Promise((resolve, reject) => {
    const dogWalked = true;
    if (dogWalked) {
      resolve(“You walked the dog!”);
    } else {
      reject(“You didn’t walk the dog.”);
    }
  });
}

function cleanKitchen() {
  return new Promise((resolve, reject) => {
    const cleaned = false;
    if (cleaned) {
      resolve(“You cleaned the kitchen!”);
    } else {
      reject(“You didn’t clean the kitchen.”);
    }
  });
}

function takeTrash() {
  return new Promise((resolve, reject) => {
    const trashTakenOut = true;
    if (trashTakenOut) {
      resolve(“You took out the trash!”);
    } else {
      reject(“You didn’t take out the trash.”);
    }
  });
}

You can chain these tasks together using the then method to handle each one:

walkDog()
  .then((message) => {
    console.log(message);
    return cleanKitchen();
  })
  .then((message) => {
    console.log(message);
    return takeTrash();
  })
  .then((message) => {
    console.log(message);
    console.log(“All tasks are done!”);
  })
  .catch((error) => {
    console.log(“Oops! Something went wrong:”, error);
  });

Working with Multiple Promises

You can also handle multiple asynchronous tasks at once:

  • Promise.all: Waits for all tasks to finish, and fails if any task fails.
  • Promise.allSettled: Waits for all tasks to finish, but it handles both successes and failures.
  • Promise.race: Returns as soon as the first task finishes, no matter if it’s a success or failure.
  • Promise.any: Returns as soon as the first successful task finishes.

Here’s how they work:

Promise.all Example:

Promise.all([walkDog(), cleanKitchen(), takeTrash()])
  .then((results) => {
    console.log(“All tasks completed successfully:”, results);
  })
  .catch((error) => {
    console.error(“Oops! One of the tasks failed:”, error);
  });

Promise.allSettled Example:

Promise.allSettled([walkDog(), cleanKitchen(), takeTrash()])
  .then((results) => {
    results.forEach((result) => {
      if (result.status === “fulfilled”) {
        console.log(“Task successful:”, result.value);
      } else {
        console.error(“Task failed:”, result.reason);
      }
    });
  });

Promise.race Example:

Promise.race([walkDog(), cleanKitchen(), takeTrash()])
  .then((result) => {
    console.log(“The first task to finish:”, result);
  })
  .catch((error) => {
    console.error(“The first task failed:”, error);
  });

Promise.any Example:

Promise.any([walkDog(), cleanKitchen(), takeTrash()])
  .then((result) => {
    console.log(“The first successful task:”, result);
  })
  .catch((error) => {
    console.error(“All tasks failed:”, error);
  });

Leave a Reply