Promise.all vs Promise.allSettled in JavaScript
好的,我现在需要帮助用户总结一篇文章的内容,控制在100字以内。首先,我得仔细阅读用户提供的文章内容,理解其主要观点。 文章主要讨论了JavaScript中的Promise.all和Promise.allSettled的区别。Promise.all会在任何一个Promise失败时立即拒绝,而Promise.allSettled则会等待所有Promise完成,无论成功与否。此外,文章还提到了Promise.race,它会在第一个Promise完成时就返回结果。 接下来,我需要将这些要点浓缩到100字以内。要确保涵盖主要区别和每个方法的行为。同时,语言要简洁明了,避免使用复杂的术语。 可能的结构是先介绍Promise.all和allSettled的不同,然后提到race的作用。这样既全面又简洁。 最后,检查字数是否符合要求,并确保表达清晰。 </think> 文章介绍了JavaScript中`Promise.all`和`Promise.allSettled`的区别:前者在任一Promise失败时立即拒绝,后者等待所有Promise完成并返回结果状态。此外还提到了`Promise.race`,它会返回最先完成的Promise的结果。 2020-5-14 16:50:44 Author: blog.jonlu.ca(查看原文) 阅读量:0 收藏

I was reading the MDN docs on JavaScript promises and thought the difference between Promise.all and Promise.allSettled was interesting and slightly nuanced, and would be fun to discuss.

About Promises

From the docs linked above:

A Promise is a proxy for a value not necessarily known when the promise is created. It allows you to associate handlers with an asynchronous action's eventual success value or failure reason.

A Promise is in one of these states:

> pending: initial state, neither fulfilled nor rejected.

> fulfilled: meaning that the operation completed successfully.

> rejected: meaning that the operation failed.

You can instantiate a promise like so:

const someFutureValue = new Promise((resolve, reject) => {
  setTimeout(resolve, 2000);
});

Difference between all and allSettled

tldr; Promise.all will immediately reject if any of the promises fail to resolve, wherease Promise.allSettled will await the completion of all promises.

Promise.all()

Promise.all() is passed an iterable (usually an array of other promises) and will attempt to resolve all of them. If any of these promises throws an exception or rejects, Promise.all will immediateley invoke its reject.

You should always surround Promise.all() with a try/catch or a .catch().

const promiseFunction = async () => {
  const resolvingPromise = new Promise((resolve) => setTimeout(() => resolve("success"), 1000));
  const rejectingPromise = new Promise((resolve, reject) => setTimeout(() => reject("fail"), 500));
  try {
    const allPromises = await Promise.all([resolvingPromise, rejectingPromise]);
  } catch (e) {
    // e is 'fail', which is  the contents of the reject function from rejectingPromise
    // resolvingPromise =  Promise {<pending>}
    console.log(e);
  }
};
promiseFunction();

In the above code snippet, when console.log(e) is called, the status of resolvingPromise will still be pending. The code invoked in the catch statement is run roughly 500ms after the promiseFunction invocation - since rejectingPromise rejects after 500ms.

const promiseFunction = async () => {
  const resolvingPromise = new Promise((resolve) => setTimeout(() => resolve("success"), 1000));
  const resolvingPromiseTwo = new Promise((resolve, reject) => setTimeout(() => resolve("successTwo"), 500));
  try {
    const allPromises = await Promise.all([resolvingPromise, resolvingPromiseTwo]);
    console.log(allPromises);
    // allPromises = ['success', 'successTwo']
  } catch (e) {
    // this code block is never executed
    console.log(e);
  }
};
promiseFunction();

The Promise.all resolves 1000ms after invocation - resolvingPromiseTwo resolves after 500ms, and resolvingPromise resolves after 1s, which completes all the promises, which allows the Promise.all promise to resolve. Promise.all() returns an array with the resolved value of each of the Promises passed to it, in the order in which they are passed. In the above case, it is an array of strings = ['success', 'successTwo'].

Promise.allSettled()

Promise.allSettled() is also passed an iterable (usually an array of other promises) and will attempt to resolve all of them. If any of these promises throws an exception or rejects, its status is set to rejected.

An important note is that Promise.allSettled can never reject. You do not need to wrap it with try/catch - it will always resolve.

const promiseFunction = async () => {
  const resolvingPromise = new Promise((resolve) => setTimeout(() => resolve("success"), 1000));
  const rejectingPromise = new Promise((resolve, reject) => setTimeout(() => reject("fail"), 500));
  try {
    const allPromises = await Promise.allSettled([resolvingPromise, rejectingPromise]);
    console.log(allPromises);
    // allPromises
    // [
    //   {status: "fulfilled", value: 'success'},
    //   {status: "rejected",  reason: 'fail'}
    // ]
  } catch (e) {
    // this code block is never executed
    console.log(e);
  }
};
promiseFunction();

Promise.allSettled resolves after 1s - it awaits all the promises, regardless of their status or if they reject. It then returns an array of objects. It's up to the caller to check if each promise fulfilled or rejected. If it fulfilled, the value of the object will be contain what was resolved. If the status is rejected, it will contain a key called reason, which is what was thrown or rejected.

Bonus: Promise.race

There is also another interest function in Promise called Promise.race.

The Promise.race() method returns a promise that fulfills or rejects as soon as one of the promises in an iterable fulfills or rejects, with the value or reason from that promise. 1

const promiseFunction = async () => {
  const resolvingPromise = new Promise((resolve) => setTimeout(() => resolve("success"), 1000));
  const resolvingPromiseTwo = new Promise((resolve, reject) => setTimeout(() => resolve("successTwo"), 500));
  try {
    const racedPromises = await Promise.race([resolvingPromise, resolvingPromiseTwo]);
    console.log(racedPromises);
    // both promises would've resolved, but resolvingPromiseTwo was faster, so racedPromises = 'successTwo'`
  } catch (e) {
    // this code block is only executed if the first promise to settle rejects/throws
    console.log(e);
  }
};
promiseFunction();

In the above, console.log(racedPromises) is called 500ms after invocation - both promises would've resolved, but resolvingPromiseTwo was faster, and it is what Promise.race resolves with.

This is pretty specific behavior - most of the time this is probably not what you want, but it's pretty neat!

Footnotes

  1. https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/race


文章来源: https://blog.jonlu.ca/posts/promises
如有侵权请联系:admin#unsafe.sh