# 实现Promise.all()

对于 Promise.all(arr) 来说,在参数数组中所有元素都变为决定态后,然后才返回新的 promise。

const p1 = request(`http://some.url.1`)
const p2 = request(`http://some.url.2`)
Promise.all([p1, p2])
  .then((datas) => { // 此处 datas 为调用 p1, p2 后的结果的数组
    return request(`http://some.url.3?a=${datas[0]}&b=${datas[1]}`)
  })
  .then((data) => {
    console.log(msg)
  })

原理实现如下:

function promiseAll(promises) {
  return new Promise(function (resolve, reject) {
    // 传入值类型判断
    if (!Array.isArray(promises)) {
      return reject(new TypeError("argument must be anarray"))
    }

    var countNum = 0;
    var promiseNum = promises.length;
    var resolvedvalue = new Array(promiseNum);
    for (let i = 0; i < promiseNum; i++) {
      Promise.resolve(promises[i]).then(value => {
        countNum++;
        resolvedvalue[i] = value;
        if (countNum === promiseNum) {
          return resolve(resolvedvalue)
        }
      }, reason => {
        return reject(reason)
      })
    }
  })
}

var p1 = Promise.resolve(1),
  p2 = Promise.resolve(2),
  p3 = Promise.resolve(3);
promiseAll([p1, p2, p3]).then(function (value) {
  console.log(value) // [ 1, 2, 3 ]
})

谈谈Promise.all的错误处理:

有时候我们使用Promise.all()执行很多个网络请求,可能有一个请求出错,但我们并不希望其他的网络请求也返回reject,要错都错,这样显然是不合理的。如何做才能做到promise.all中即使一个promise程序reject,promise.all依然能把其他数据正确返回呢?

var p1 = new Promise(function (resolve, reject) {
  setTimeout(function () {
    resolve(1);
  }, 0)
});
var p2 = new Promise(function (resolve, reject) {
  setTimeout(function () {
    try {
      console.log(XX.BBB);
    }
    catch (exp) {
      resolve("error");
    }
  }, 100)
});
var p3 = new Promise(function (resolve, reject) {
  setTimeout(function () {
    resolve(3);
  }, 200)
});

Promise.all([p1, p2, p3]).then(function (results) {
  console.log("success")
  console.log(results);
}).catch(function (r) {
  console.log("err");
  console.log(r);
});

// 打印结果:
// success
// [ 1, 'error', 3 ]