手写 Promise.all

手写 Promise.all

Promise.all 的使用方法

  • 语法
    Promise.all(iterable);

  • 参数
    iterable
    一个可迭代对象,如 Array 或 String。

  • 返回值

    • 如果传入的参数是一个的可迭代对象,则返回一个已完成(already resolved)状态的 Promise。
    • 如果传入的参数不包含任何 promise,则返回一个异步完成(asynchronously resolved)Promise。
    • 其它情况下返回一个处理中(pending)的Promise。这个返回的 promise 之后会在所有的 promise 都完成或有一个 promise 失败时异步地变为完成或失败。返回值将会按照参数内的 promise 顺序排列,而不是由调用 promise 的完成顺序决定。

实现 Promise.all

Promise.myAll = function (iterable) {
    
    
  return new Promise((resolve, reject) => {
    
    
    if (typeof Object(iterable)[Symbol.iterator] === 'undefined') {
    
    
      // 没有 Symbol.iterator 接口
      const type = Object.prototype.toString.call(iterable).slice(8, -1).toLowerCase();
      throw new Error(`${
      
      type} ${
      
      iterable.toString()} is not iterable (cannot read property Symbol(Symbol.iterator))`)
    }

    const array = [...iterable]; // 将可迭代对象转数组并用来保存运行结果
    const allNum = array.length;
    if (!allNum) return resolve([]);

    const values = []; // 保存运行结果
    let cnt = 0; // 保存成功的次数
    array.forEach((item, index) => {
    
    
      Promise
        .resolve(item) // 可以将非 promise 转化
        .then(res => {
    
    
          cnt++;
          values[index] = res;
          if (cnt === allNum) resolve(values);
        })
        .catch(err => reject(err)); // 如果失败了将返回第一个失败的结果
    });
  })
}

功能测试

var p1 = Promise.resolve(3);
var p2 = 1337;
var p3 = new Promise((resolve, reject) => {
    
    
  setTimeout(resolve, 3000, 'foo');
});

Promise
  .myAll([p1, p2, p3])
  .then(console.log); // [3, 1337, 'foo']
var p1 = Promise.resolve(3);
var p2 = 1337;
var p3 = new Promise((resolve, reject) => {
    
    
  setTimeout(reject, 3000, 'foo');
});

Promise
  .myAll([p1, p2, p3])
  .then(values => console.log(values))
  .catch(console.log); // 'foo'
Promise.myAll('123').then(console.log); // [ '1', '2', '3' ]
Promise.myAll([]).then(console.log); // []
Promise.myAll(666).then(console.log); // Error: number 666 is not iterable (cannot read property Symbol(Symbol.iterator))

猜你喜欢

转载自blog.csdn.net/ox4f5da2/article/details/128656532