Handwritten Promise.all

Handwritten Promise.all

How to use Promise.all

  • grammar
    Promise.all(iterable);

  • Parameters
    iterable
    An iterable object such as Array or String.

  • return value

    • If the passed argument is an empty iterable, returns a Promise with already resolved state.
    • If the passed parameter does not contain any promises, returns an asynchronously resolved (asynchronously resolved) Promise.
    • Otherwise a pending Promise is returned. The returned promise will then asynchronously become fulfilled or failed when all promises are fulfilled or when one promise fails. The return value will be in the order of the promises in the parameters, not determined by the order in which the calling promises are fulfilled.

Implement 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)); // 如果失败了将返回第一个失败的结果
    });
  })
}

function test

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))

Guess you like

Origin blog.csdn.net/ox4f5da2/article/details/128656532