11

技术篇 - 如何使用 Promise.all()

 2 years ago
source link: https://segmentfault.com/a/1190000040514839
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.all()

hello, 大家好,我是前端学长Joshua
热心于做开源,写文章,目的为帮助在校大学生,刚入职场的小伙伴可以尽快搭建自己的前端学习体系。
如果你有学习上的困惑,欢迎关注我,找我交流,我实时回复大家

Promise.all() 的介绍

Promise.all(promisesArrayOrIterable) 是javascript中的一个辅助函数。它可以帮助我们一次,并行处理多个promise, 然后将结果聚合到一个数组里边,这是聚合结果,不是说返回结果哦。

它实际上是返回一个promise对象。

参数:promise数组

const allPromise = Promise.all([promise1, promise2, ...]);

然后你可以通过 .then 来获取到 Promise.all(promisesArrayOrIterable) 处理之后的聚合结果

allPromise.then(values => {
  values; // [valueOfPromise1, valueOfPromise2, ...]
}).catch(error => {
  error;  // rejectReason of any first rejected promise
});

或者是使用async / await 语法:

try {
  const values = await allPromise;
  values; // [valueOfPromise1, valueOfPromise2, ...]
} catch (error) {
  error;  // rejectReason of any first rejected promise
}s

关于 Promise.all() 中,最有趣的点就是,对于参数中,promise被 resolve / 被 reject 的处理方式。

  1. 如果所有 promise 都成功解析,Promise.all() 会将每个 promise 的已完成值 聚合 到数组。我们可以按照原来参数中每一个promise的顺序,获取到他们对应的完成值。
  2. 如果有其中一个 promise 被拒绝,那么 Promise.all() 会以同样的原因立即拒绝(不等待其他 Promise 解决)。

所以,Promise.all()的特点,记住三个词就可以了:

下面的例子,都是围绕这三个核心词来展开的。

在进入例子之前,我们先来写两个辅助函数:
resolveTimeout(value, delay):回返回一个promise对象,这个promise对象会延迟一段时间之后,触发 resolve
rejectTimeout(reason, delay):回返回一个promise对象,这个promise对象会延迟一段时间之后,触发 reject

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

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

所有 promise 都被 reslove

const allPromise = Promise.all([
  resolveTimeout(['potatoes', 'tomatoes'], 1000),
  resolveTimeout(['oranges', 'apples'], 1000)
]);

// wait...
const lists = await allPromise;

// after 1 second
console.log(lists); 
// [['potatoes', 'tomatoes'], ['oranges', 'apples']]

从代码中,我们可以知道:

  1. promises 数组的顺序就是聚合结果的顺序。
  2. 所有 promise 都被 reslove,resolve之后,每一个promsie的结果会被聚合到数组中

有一个 promise 被 reject

const allPromise = Promise.all([
  resolveTimeout(['potatoes', 'tomatoes'], 1000),
  rejectTimeout(new Error('Out of fruits!'), 1000)
]);

try {
  // wait...
  const lists = await allPromise;
} catch (error) {
  // after 1 second
  console.log(error.message); // 'Out of fruits!'
}

从代码中,我们可以知道:

  1. 只要有一个promise是被reject, Promise.all就会立即拒绝并返回相同的错误。
    这就是快速失败。

模拟源码实现

async function myPromiseAll (arr) {
  const resultArr = [];
  for (let i = 0; i < arr.length; i ++) {
    try {
      const data = await arr[i];
      resultArr.push(data); // promise被reaolve, push 到 resultArr中
    } catch (e) {
      throw e; // 只要有一个被reject(就是触发错误), 马上抛出错误
    }
  }
  return resultArr;
}

Promise.all([...]) 是一个有用的辅助函数,它允许您使用快速失败策略中,并行执行异步操作,并将结果聚合到一个数组中。

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

About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK