Promise.all功能分析:
- 方法接受一个数组(可以不是数组,但须具有Iterator接口)作为参数;
- 方法返回一个新的Promise实例;
- 数组成员中不是Promise实例的会转成Promise实例;
- 当数组成员状态都变成fulfilled时,返回的Promise实例状态也变成fulfilled,数组成员的结果按顺序组成新数组,作为返回的Promise实例的结果;
- 当数组任意一个成员状态变成时rejected时,返回的Promise实例状态变成rejected,第一个状态变成rejected的结果作为返回的Promise实例的结果。
实现(新方法命名为promiseAll):
根据功能第1、2点——接收一个数组参数,返回一个Promise实例
const promiseAll = (promises) => {
return new Promise((resolve, reject) => {
});
}
遍历数组。因为参数可以不是数组,但须具有Iterator接口,所以使用for of循环。根据功能第3点,使用Promise.resolve处理数组成员
const promiseAll = (promises) => {
return new Promise((resolve, reject) => {
for (const promise of promises) {
Promise
.resolve(promise)
}
});
};
根据功能第4点,声明一个变量responses作为新数组存储数组成员fulfilled的结果。注意responses的成员顺序与原数组顺序保持一致。并在所有数组成员都变成fulfilled状态时resolve(responses)
const promiseAll = (proms) => {
return new Promise((resolve, reject) => {
const promises = Array.from(proms);
const promiseLength = promises.length;
const responses = new Array(promiseLength);
// fulfilled状态的数量
let fulfilledQuantity = 0;
for (const [i, promise] of promises.entries()) {
Promise
.resolve(promise)
.then((res) => {
responses[i] = res;
fulfilledQuantity++;
if (fulfilledQuantity === promiseLength) {
resolve(responses)
}
})
}
});
};
根据功能第5点,任意一个成员状态变成时rejected时,reject这个成员结果。下面是代码最终结果
const promiseAll = (promises) => {
return new Promise((resolve, reject) => {
const promiseLength = promises.length;
const responses = new Array(promiseLength);
// fulfilled状态的数量
let fulfilledQuantity = 0;
for (const [i, promise] of promises.entries()) {
Promise
.resolve(promise)
.then((res) => {
responses[i] = res;
fulfilledQuantity++;
if (fulfilledQuantity === promiseLength) {
resolve(responses)
}
})
.catch((error) => {
reject(error)
});
}
});
};
测试
const p1 = new Promise((resolve, reject) => {
resolve('p1')
});
const p2 = new Promise((resolve, reject) => {
setTimeout(() => {
resolve('p2')
}, 1000);
});
const p3 = new Promise((resolve, reject) => {
reject('p3 error')
});
promiseAll([p1, p2])
.then((res) => {
console.log(res)
})
.catch((err) => {
console.log(err)
});
promiseAll([p1, p2, p3])
.then((res) => {
console.log(res)
})
.catch((err) => {
console.log(err)
});
运行结果为: 先打印“p3 error”,1秒后打印“[ 'p1', 'p2' ]”,符合预期结果。