手写 Promise.all
功能:并行执行一组 Promise,全部成功才
resolved,任意一个失败则立刻rejected,并且保证返回结果的顺序与输入顺序一致。
思路
- 遍历传入的可迭代对象
promises,为每一项包装Promise.resolve:- 这样即使输入中有普通值,也会被转成已完成的 Promise;
- 使用
result[index]按输入顺序存放每个 Promise 的结果; - 用
fulfilled记录已经成功的数量,当fulfilled === count时,整体resolve(result); - 如果没有任何输入(
count === 0),直接返回空数组。
代码
js
/**
* Promise.all 完成并行任务,接收 promise 数组,返回一个 promise
* 在所有输入的 Promise 都成功时才会 resolved,并返回一个包含所有结果的数组
* 任何一个输入的 Promise 被拒绝,返回的 Promise 会立即被拒绝,并返回该拒绝的错误
* 注意:Promise.all 输入输出顺序不会变
* @param {iterator} promises
*/
Promise.myAll = function(promises) {
return new Promise((res, rej) => {
let count = 0;
let fulfilled = 0;
const result = [];
for (const promise of promises) {
const index = count;
count++;
// Promise.resolve() 用于将现有对象转为 Promise 对象,若已是 Promise 对象则原封不动返回
Promise.resolve(promise).then((data) => {
result[index] = data;
fulfilled++;
if (fulfilled === count) {
res(result);
}
}, rej);
}
if (count === 0) {
res([]);
}
});
}