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