手写Promise.all 支持可迭代对象

网上看了一些Promise.all实现方式,发现实现多少不完整,有的使用for of确实可以迭代,但是无法保证promise完成的顺序。有的保证了顺序,但是却没有支持可迭代对象(如字符串,generator)。 综合了一下大家的实现方式,整理代码如下:

Promise.all = function (iterator) {
  const type = Object.prototype.toString.call(iterator).slice(8, -1).toLocaleLowerCase();
  const isIterable = (
    ((typeof iterator === "object" && iterator !== null) ||
      typeof iterator === "string") &&
    typeof iterator[Symbol.iterator] === "function"
  );
  if (isIterable) {
    let resolveCount = 0;
    const promiseResult = [];
    iterator = Array.from(iterator);
    const promiseCount = iterator.length;

    return new Promise((resolve, reject) => {
      if (!iterator.length) {
        resolve([]);
      }
      iterator.forEach((promise, index) => {
        Promise.resolve(promise).then(
          (value) => {
            resolveCount++;
            promiseResult[index] = value;
            if (promiseCount === resolveCount) {
              resolve(promiseResult);
            }
          },
          (reason) => {
            reject(reason);
          }
        );
      });
    });
  } else {
    throw new TypeError(`${type} ${iterator} is not iterable`);
  }
};

const p1 = new Promise((resolve) => {
  setTimeout(resolve.bind(null, 1), 3000);
});
const p2 = new Promise((resolve) => {
  setTimeout(resolve.bind(null, 2), 100);
});
const p3 = new Promise((resolve) => {
  setTimeout(resolve.bind(null, 3), 500);
});
function* gen() {
  yield 1;
  yield 2;
  yield 3;
}
Promise.all().then((v) => {
  console.log(v);
});
Promise.all({}).then((v) => {
  console.log(v);
});
Promise.all([]).then((v) => {
  console.log(v);
});
Promise.all([p1, p2, p3]).then((v) => {
  console.log(v);
});
Promise.all("123").then((v) => {
  console.log(v);
});
Promise.all(gen()).then((v) => {
  console.log(v);
});

 

posted @ 2020-12-06 17:32  zt123123  阅读(1486)  评论(0编辑  收藏  举报