简述
- Promise.all 用于并行执行多个 Promise;
- 接收一个promise实例的iterable(数组)作为参数,并返回一个新的Promise实例;
- 返回的新的Promise实例会在给定的Promise都成功解决后才会被解决,其结果是由每个Promise结果组成的数组
- 如果一个Promise被拒绝,整个Promise.all会被立即拒绝,不会再等待其他Promise完成
手写
function myPromiseAll(iterable) {
return new Promise((resolve,reject) => {
const promises = Array.from(iterable);
// 定义Promise对象resolve的数组
const result = [];
// 定义一个计数器用来判断是否所有的promise执行完毕
let count = 0;
// 并发执行每一个promise
for (let i = 0; i < promises.length; i++) {
// 确保每项都可被当作一个Promise来处理,即使传入非Promise值
Promise.resolve(promises[i]).then(res => {
result[i] = res;
count++;
if (count === promises.length) {
resolve(result);
}
}).catch(err => reject(err))
}
})
}
注意:
- 并不是push进result数组的,而是通过下标的方式进行存储,这是因为我们为了保证输出的顺序,因为Promise对象执行的时间可能不同,push的话会破坏顺序。
- 通过计数标志来判断是否所有的promise对象都执行完毕了,因为在then中表示该promise对象已经执行完毕。
注意问题
1 入参是串行 or 并行执行 —— 并行
验证代码如下:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
</head>
<body>
<script>
// 手写promise all
function myPromiseAll(iterable) {
return new Promise((resolve, reject) => {
const promises = Array.from(iterable);
// 定义Promise对象resolve的数组
const result = [];
// 定义一个计数器用来判断是否所有的promise执行完毕
let count = 0;
// 并发执行每一个promise
for (let i = 0; i < promises.length; i++) {
Promise.resolve(promises[i])
.then((res) => {
result[i] = res;
count++;
if (count === promises.length) {
resolve(result);
}
})
.catch((err) => reject(err));
}
});
}
const p1 = new Promise(async (resolve) => {
console.log('p1开始');
await new Promise((resolve) => setTimeout(resolve, 1000));
console.log('p1结束');
});
const p2 = new Promise(async (resolve, reject) => {
console.log('p2开始');
await new Promise((resolve) => setTimeout(resolve, 3000));
console.log('p2结束');
});
myPromiseAll([p1, p2])
.then((res) => {
console.log(333, res);
})
.catch((err) => {
console.log(err);
});
</script>
</body>
</html>