ES6+| promise.all特性与实用场景

文章目录

  • 前言
  • 返回顺序与完成时间
  • rejected情况处理
  • 实际场景与改良

前言

Promise.all常用于处理多个并行的异步操作。
Promise.all可接受一个可迭代对象,一般为Promise组成的数组,并在所有Promise都完成或遇到第一个rejected后返回结果。
本文将通过实验,验证Promise.all的几个特性与实用场景下的优化
本文依旧以setTimeout代表异步操作,实验涉及四个异步操作,如下:

// 四个promise封装的异步动作,其中三个返回resolve,一个返回reject
function asyncAction1() {
  let p = new Promise(function(resolve, reject) {
    setTimeout(function() {
      resolve('1');
    }, 3000);
  });
  return p;
}

function asyncAction2() {
  let p = new Promise(function(resolve, reject) {
    setTimeout(function() {
      resolve('2');
    }, 2000);
  });
  return p;
}

function asyncAction3() {
  let p = new Promise(function(resolve, reject) {
    setTimeout(function() {
      resolve('3');
    }, 1000);
  });
  return p;
}

function asyncAction4() {
  let p = new Promise(function(resolve, reject) {
    setTimeout(function() {
      reject('error');
    }, 4000);
  });
  return p;
}

返回顺序与完成时间

promise.all返回数据的顺序和参数列表申明顺序相同,与异步完成时间无关。
尽管返回数据时,是按顺序的,但是执行时,所有promise都是并行的,promise.all在所有promise都fullfilled的情况下,完成时间以最晚fullfilled的promise为准。

console.log(new Date());
promiseArr = [asyncAction1(), asyncAction2(), asyncAction3()];
Promise.all(promiseArr).then(res => {
  console.log(res);
  console.log(new Date());
});

输出:
在这里插入图片描述

rejected情况处理

promise.all只返回一个promise,所以当遇到第一个rejected的promise时,就会立即返回rejected,其他fullfilled的promise即使执行了也不会返回。

promiseArr = [asyncAction1(), asyncAction2(), asyncAction3(), asyncAction4()];
Promise.all(promiseArr)
  .then(res => {
    console.log(res);
  })
  .catch(err => {
    console.log(err);
  });

输出:
在这里插入图片描述

实际场景与改良

有时候,我们使用Promise.all同时发起若干异步请求,但并不希望因为一个失败而放弃其余请求,此时我们可以对promise队列进行改动,最终使得rejected信息也以fullfilled的状态输出。

当catch捕获rejected信息后,promise的链条就恢复了,我们可以在catch中将错误信息进行返回,那么下一步then返回的promise将会成为fufilled状态,错误信息将成为resolve回调函数的参数。

asyncAction4()
  .catch(err => {
    return err;
  })
  .then(res => {
    console.log(res);
  });

输出:
在这里插入图片描述
因此我们可以通过map方法对promiseArr中返回rejected状态的promise进行上述处理,保证promise.all始终能够完成,而错误信息也出现在resolve回调函数的参数数组中。

Promise.all(promiseArr.map(p => p.catch(err => err)))
  .then(res => {
    console.log(res);
  })
  .catch(err => {
    console.log(err);
  });

输出:
在这里插入图片描述

你可能感兴趣的:(ES6+)