DEV Community

Ayako yk
Ayako yk

Posted on

More About Promise

In the previous blog article (Difference Between Promise And Async), I talked about the basics of a Promise, with these topics:

  1. Synchronous vs Asynchronous
  2. Promise
  3. Async / Await
  4. Error handlings.

Today, I learned a little more about a Promise, and share it here.

This article includes these topics:

  1. Review of Promise
  2. Promise chaining
  3. Promise.all()
  4. Promise.any()
  5. Promise.race()

Promise
A Promise is a returned object of the asynchronous operation, and there are two possible results: success and failure. So, we need two functions (callback functions) depending on whether it’s a success or not, which are resolve and reject, respectively.

const example = new Promise( (resolveFunction,rejectFunction) => {
    resolveFunction();   // when successful
    rejectFunction();    // when failed
});

// When success
example.then(() => {
    // This callback function is called
}).catch(error => {
    // This callback function is not called
})

// When failure
example.then(() => {
    // This callback function is not called
}).catch(error => {
    console.log(error.message)
})
Enter fullscreen mode Exit fullscreen mode

Promise Chaining
The then() function (and catch() function as well) returns a new promise, so we can execute multiple asynchronous operations. This is a promise chain, and useful for complex code.

const example = new Promise(function (resolve, reject) {
  setTimeout(() => resolve(1), 1000);
})
  .then(function (result) {
    alert(result); // 1
    return result * 2;
  })
  .then(function (result) {
    alert(result); // 2
    return result * 2;
  })
  .then(function (result) {
    alert(result); // 4
    return result * 2;
  });
Enter fullscreen mode Exit fullscreen mode

*This example is from The Modern JavaScript Tutorial

The first then() method receives “1” as an argument, and returns a new value multiplied by 2. Then, the second then() method receives the new value “2”, and returns another new value…

Since a promise passes a new instance, we can add catch() method before then() method.

const example = new Promise((resolve, reject) => {
  resolve();
})
  .then(() => {
    throw new Error("Something failed");

    console.log("This is not called");
  })
  .catch((err) => {
    console.error(err); // "Something failed"
  })
  .then(() => {
    console.log("This is called");
  });
Enter fullscreen mode Exit fullscreen mode

Finally()
The finally() method is always called whether it’s success or failure.
This is just like try…catch…finally

const example = () => {
  return new Promise((resolve, reject) => {
    if (Math.random() > 0.5) {
      resolve("over 0.5");
    } else {
      reject(new Error("Failed: less than or equal to 0.5"));
    }
  });
};

example()
  .then((result) => {
    console.log(result);
  })
  .catch((err) => {
    console.error(err);
  })
  .finally(() => {
    console.log("Finally is always called");
  });
Enter fullscreen mode Exit fullscreen mode

Promise.all
Promise.all() takes an iterable of promises (usually, an array of promises) and returns a new promise that resolves to an array.
When all of the input’s promises resolve or if the input iterable contains no promises, the new promise resolves.
If any of the input’s promises reject or non-promises throw an error, it rejects immediately.

Promise.any
Promise.any() takes an iterable of promises. It returns a single promise that resolves as soon as any of the promises in the iterable fulfills. The value is the fulfilled promise.

Promise.race
Promise.race() returns a promise that fulfills or rejects as soon as one of the promises in an iterable fulfills or rejects.

Promise.any() takes the first fullfilled Promise.
Promise.race() takes the first settled Promise.

Promise.race

const promise1 = new Promise((resolve, reject) => {
  setTimeout(resolve, 500, "one");
});

const promise2 = new Promise((resolve, reject) => {
  setTimeout(reject, 100, "two");
});

Promise.race([promise1, promise2])
  .then((value) => {
    console.log("succeeded with value:", value);
  })
  .catch((reason) => {
    // Only promise1 is fulfilled, but promise2 is faster
    console.log("failed with reason:", reason);
  });
// expected output: "failed with reason: two"
Enter fullscreen mode Exit fullscreen mode

Promise.any

const promise1 = new Promise((resolve, reject) => {
  setTimeout(resolve, 500, "one");
});

const promise2 = new Promise((resolve, reject) => {
  setTimeout(reject, 100, "two");
});

const example = Promise.any([promise1, promise2])
  .then((value) => {
    // Only promise1 is fulfilled, even though promise2 settled sooner
    console.log("succeeded with value:", value);
  })
  .catch((reason) => {
    console.log("failed with reason:", reason);
  });
// expected output: "succeeded with value: one"
Enter fullscreen mode Exit fullscreen mode

*These examples are from Mozilla

Here’s a recap:

  1. A Promise is a returned object of the asynchronous operation and returns either success/resolve or failure/reject.
  2. Multiple callbacks can be added (eg. then().then().catch().then() ) because each method returns a new Promise, and this is called Promise chaining.
  3. Promise.all() takes an iterable, and if all of them resolve, it returns an array with all Promises.
  4. Promise.any() takes an iterable, and if any of them resolves, it returns the first fulfilled Promise.
  5. Promise.race() takes an iterable, and it returns the first settled Promise (It could be resolve or reject)

I was working on an open-source project which is a quite large-scaled one, and we used Promise.all() methods. I believe it’s a must to understand a Promise, so I hope this article helps you as well.

Top comments (0)