走进Promise-第六弹:promise.all方法的实现

269 阅读2分钟

前面几弹已经对promise基础功能,深入剖析并实现,现在再来对promiseallresolvefinallycatch方法逐一实现。

all方法功能及特点:

  1. all方法用来解决异步并发问题,允许我们异步代码调用的顺序,得到异步的代码的执行结果。
  2. promise.all方法接收一个数组作为参数,这个数组中可以填入任意值,包括普通值和promise对象,数组中传入值的顺序一定是执行结果的顺序。
  3. promise.all方法的返回值也是一个promise对象,所以可以在promise.all后使用then方法。
  4. all方法中所有的promise对象状态都是成功的,all方法最后的结果才是成功的,如果有一个是失败的,最后的结果是失败的。
  5. 使用promise.all的方式调用,所以all方法是一个静态方法。

解决思路:

  • 声明静态方法all
  • 声明result变量存放,promise对象。
  • 循环传入的数组,判断当前值是否是promise对象的实例,如果是即为promise对象,存放到result数组中,如果不是就是普通值,直接调用resolve方法传递到下一个promise对象。
  • 代码中for循环执行完立即执行resolve方法,那么异步逻辑无法处理,这里声明index变量,每次往数组中添加后index++,然后和result长度比较,相等的时候即为处理完成。

**testPromise.js**中:

/**
   * 静态方法使用static关键字声明
   * 1.接收数组作为参数,这里定义形参为array
   * 2.返回的对象是promise对象
   * 3.循环数组,判断当前的传入值是普通值还是promise对象,如果是普通值直接调用resolve方法返回
   * 4.如何判断,即判断当前传入值是否在这个testPromsie类中
   * 5.且需要一个数组接收处理后的promise对象
   */
  static all (array) {
    let result = [];
    let index = 0;
  
    return new testPromise((resolve, reject) => {
      // 定义方法将promise放到result数组
      function addData (key, value) {
        result[key] = value;
        // 对异步逻辑进行处理
        index ++;
        if (index === array.length) {
          resolve(result);
        }
      }

      for (let i = 0; i < array.length; i++) {
        // array[i]是否是testPromise的一个实例
        if (array[i] instanceof testPromise) {
          // promise对象
          array[i].then(value => addData(i, value), reason => reject(reason));
        } else {
          // 普通值
          addData(i, array[i])
        }
      }

      // 这里循环完立即执行,异步逻辑就不会处理,会导致这个异步没有执行
      // resolve(result);
    })

  }

**index.js**中测试代码:

// 7.promise.all方法
function p1 () {
  return new testPromise(function (resolve, reject) {
    setTimeout(() => {
      resolve("p1")
    }, 2000);
  })
}

function p2 () {
  return new testPromise(function (resolve, reject) {
    resolve("p2")
  })
}
testPromise.all(['a', 'b', p1(), p2(), 'c'])
  .then(result => {
    console.log(result);
  })

测试结果:

打印结果说明all方法是可行的。