1. 程式人生 > 實用技巧 >手寫Promise.all 支援可迭代物件

手寫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); });