1

Promise.allSettled()的用法

 1 year ago
source link: https://www.fly63.com/article/detial/12252
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

Promise.allSettled()是一个JavaScript方法,它返回一个promise,在所有给定的promise都完成(成功或失败)后完成。与Promise.all()方法不同,Promise.allSettled()方法不会因为某个promise失败而导致整个操作失败,它会等待所有的promise都完成,然后返回一个包含所有promise状态的数组。

示例代码

const promise1 = Promise.resolve("foo");
const promise2 = 42;
const promise3 = new Promise((resolve, reject) => {
  setTimeout(() => {
    reject("bar");
  }, 100);
});

Promise.allSettled([promise1, promise2, promise3]).then(results => {
  results.forEach(result => {
    if (result.status === "fulfilled") {
      console.log(`promise fulfilled with value: ${result.value}`);
    } else if (result.status === "rejected") {
      console.log(`promise rejected with reason: ${result.reason}`);
    }
  });
});

// expected output:
// "promise fulfilled with value: foo"
// "promise fulfilled with value: 42"
// "promise rejected with reason: bar"

在上面的示例中,我们使用Promise.allSettled()方法等待三个promise完成。其中两个promise(promise1和promise2)都成功完成,第三个promise(promise3)失败了。然后我们循环遍历结果数组,并在控制台中打印每个promise的状态和值。

总之,Promise.allSettled()方法可以让你等待所有给定的promise都完成,然后返回一个包含它们所有状态的数组。这对于需要处理多个并行操作的情况非常有用。

取水果和蔬菜

在深入研究 Promise.allSettle() 之前,我们先定义两个简单的 helper 函数

首先,resolveTimeout(value, delay)返回一个 promise ,该 promise 在经过 delay 时间后用 value 来实现

function resolveTimeout(value, delay) {
  return new Promise(
    resolve => setTimeout(() => resolve(value), delay)
  );
}

第二,rejectTimeout(reason, delay) - 返回一个 promise,在经过 delay 时间后拒绝reason。

最后,我们使用这些辅助函数来试验 promise.allsettle()。

1.All promises fulfilled

我们同时访问当地杂货店的蔬菜和水果。访问每个列表是一个异步操作:

const statusesPromise = Promise.allSettled([
  resolveTimeout(['potatoes', 'tomatoes'], 1000),
  resolveTimeout(['oranges', 'apples'], 1000)
]);
// wait...
const statuses = await statusesPromise;
// after 1 second
console.log(statuses); 
// [
//   { status: 'fulfilled', value: ['potatoes', 'tomatoes'] },
//   { status: 'fulfilled', value: ['oranges', 'apples'] }
// ]

Promise.allSettled([...])返回一个 promise statusesPromise,该 promise 在1秒内解决,就在蔬菜和水果被解决之后,并行地解决。

statusesPromise 解析为一个包含状态的数组。

  1. 数组的第一项包含有蔬菜的已完成状态:status: 'fulfilled', value: ['potatoes', 'tomatoes'] }
  2. 同样的方式,第二项是水果的完成状态: { status: 'fulfilled', value: ['oranges', 'apples'] }

2.一个 promise 被拒绝

想象一下,在杂货店里已经没有水果了。在这种情况下,我们拒绝水果的 promise。

promise.allsettle() 在这种情况下如何工作?

const statusesPromise = Promise.allSettled([
  resolveTimeout(['potatoes', 'tomatoes'], 1000),
  rejectTimeout(new Error('Out of fruits!'), 1000)
]);
// wait...
const statuses = await statusesPromise;
// after 1 second
console.log(statuses); 
// [
//   { status: 'fulfilled', value: ['potatoes', 'tomatoes'] },
//   { status: 'rejected', reason: Error('Out of fruits!') }
// ]

Promise.allSettled([...]) 返回的 promise 在 1 秒后解析为一个状态数组:

  1. 数组的第一项,蔬菜 promise 成功解析:{ status: 'fulfilled', value: ['potatoes', 'tomatoes'] }
  2. 第二项,因为水果 promise 被拒绝,所以是一个拒绝状态: { status: 'rejected', reason: Error('Out of fruits') }

即使输入数组中的第二个 promise 被拒绝,statusesPromise仍然会成功解析一个状态数组。

3.所有的 promises 都被 rejected

如果杂货店里的蔬菜和水果都卖光了怎么办?在这种情况下,两个 promise 都会被拒绝。

const statusesPromise = Promise.allSettled([
  rejectTimeout(new Error('Out of vegetables!'), 1000),
  rejectTimeout(new Error('Out of fruits!'), 1000)
]);
// wait...
const statuses = await statusesPromise;
// after 1 second
console.log(statuses); 
// [
//   { status: 'rejected', reason: Error('Out of vegetables!')  },
//   { status: 'rejected', reason: Error('Out of fruits!') }
// ]

在这种情况下,statusesPromise仍然成功地解析为一个状态数组。然而,该数组包含被拒绝的promise 的状态。

Promise.allSettled(promises)可以并行地运行 promise,并将状态(fulfilled 或reject)收集到一个聚合数组中。Promise.allSettled(...)在你需要执行平行和独立的异步操作并收集所有结果时非常有效,即使某些异步操作可能失败。

链接: https://www.fly63.com/article/detial/12252


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK