乐趣区

关于前端:并行执行多个独立的异步操作-PromiseallSettled

并行执行多个独立的异步操作 – Promise.allSettled()

<!– TOC –>

  • 并行执行多个独立的异步操作 – Promise.allSettled()

    • 介绍
    • 如何应用 Promise.allSettled()

      • 1.Promise.allSettled()
      • 2. example: 简略的应用 Promise.allSettled()

        • 2.1. 所有 promise 已实现
        • 2.2 某个 promise 已回绝
        • 2.3 所有 promise 已回绝
    • 小结:
    • 兼容性:
    • 参考
    • 动下小手

<!– /TOC –>

介绍

Promise.allSettled(promises) 是一个辅助函数,它并行运行 Promise, 并将已扭转的状态(已实现或已回绝)寄存到一个数组中,返回给开发者应用。

当您有多个彼此不依赖(或者是说互相独立的)的异步工作,您想晓得每一个 promise 工作的执行后果的时候(无论是已实现或已回绝),通常应用它。

让咱们看看 Promise.allSettled() 是如何应用的。

如何应用 Promise.allSettled()

1.Promise.allSettled()

Promise.allSettled() 可用于 并行 执行 独立 异步 操作,并收集这些异步操作实现的后果。

该函数承受一个 Promise 数组(或通常是一个可迭代的)作为参数:

const statusesPromise = Promise.allSettled(promises);

当咱们传入的参数 promises 数组 中,每一项产生了状态的扭转(无论是已实现或已回绝)之后,Promise.allSettled都会将 promises 数组 中每一项的执行后果,给咱们寄存在一个数组中,返回给开发者应用。

返回的数组 statusesPromise 中每一项的的格局如下:

  1. {status: 'fulfilled', value: value} — 如果对应的 promise 已实现
    或者
  2. {status: 'rejected', reason: reason} — 如果相应的 promise 已回绝

当所有的 promise 都被 resolved 或是 被 rejected 后,你能够应用.then 对他们进行后续的操作:

statusesPromise.then(statuses => {statuses; // [{ status: '...', value: '...'}, ...]
});

或者应用 async/await 对他们进行后续操作:

const statuses = await statusesPromise;

statuses; // [{status: '...', value: '...'}, ...]

2. example: 简略的应用 Promise.allSettled()

在理解 Promise.allSettle() 之前,让咱们定义 2 个简略的辅助函数:

首先,resolveTimeout(value, delay) —— 返回一个 promise, 这个 promise 会在一段时间之后,触发 resolve 函数:

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

其次,rejectTimeout(reason, delay)——返回一个 promise, 这个 promise 会在一段时间之后,触发 reject 函数:

function rejectTimeout(reason, delay) {
  return new Promise((r, reject) => setTimeout(() => reject(reason), delay)
  );
}

咱们就应用这两个辅助函数来试验下 Promise.allSettled() 的性能吧。

2.1. 所有 promise 已实现

上面,我会去同时执行一些异步的操作:

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([…]) 返回一个数组 statusesPromise,两个异步操作都是并行执行的。
statusesPromisePromise.allSettled([...]) 返回的一个数组,数组中的每一项都蕴含了对应的异步操作执行实现之后的状态:

  1. 数组 statusesPromise 的第一项蕴含了实现状态:{status: ‘fulfilled’, value: [‘potatoes’, ‘tomatoes’] }
    同样,
  2. 数组 statusesPromise 的第二项蕴含了实现状态:{status: ‘fulfilled’, value: [‘oranges’, ‘apples’] }。

2.2 某个 promise 已回绝

如果在多个并行独立的异步操作中,有一个异步操作是已回绝的,那么 Promise.allSettled([...]) 会怎么解决呢?

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!') }
// ]

我看下后果,咱们会很快明确:

  1. 第一项因为触发了 resolve 函数,promise 是已实现,数组的第一项是 {status: ‘fulfilled’, value: [‘potatoes’, ‘tomatoes’] }
  2. 第二项因为是触发 reject 函数,promise 是已回绝,数组的第二项状态被批改为 rejected 状态:{status: ‘rejected’, reason: Error(‘Out of Fruits’) }。

即便是有某一项是转变为 rejected 状态, 然而最初 Promise.allSettled 函数是会蕴含这一项,就它寄存在返回值中。

2.3 所有 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!') }
// ]

在这种状况下,Promise.allSettled依然会返回一个数组。只是,该数组中每一项的状态都是 rejected 状态。

小结:

Promise.allSettled(promises) 容许您 并行 执行 相互独立 的 promise, 并每一个 promise 执行之后的状态(已实现或回绝)寄存在数组中。

当您须要执行并行和独立的异步操作并获取到异步操作的所有后果时,Promise.allSettled(…) 十分有用,即便某些异步操作可能会失败。

兼容性:

参考:兼容性 很好

参考

  • TC39:Promise.allSettled
  • MDN: Promise.allSettled()

动下小手

  • 欢送关注我的 GitHub:@huangyangquang ⭐⭐
  • 欢送关注我的公众号:前端学长 Joshua
    <img src=”http://qvf3q8r5e.hn-bkt.clouddn.com/wechatQrCode.jpg” width=”50%”>
退出移动版