promise.all:只要任何一个输入的 promise 的 reject 回调执行或者输入不合法的 promise 就会立即抛出错误,并且 reject 的是第一个抛出的错误信息。若没有失败的,则最终返回一个包含所有成功结果的数组
promise.race:一旦迭代器中的某个 promise resolved或rejected,返回的 promise 就会resolved或rejected。
在实现之前,先来体验一下promise.all
和promise.race
的使用:
const p1 = Promise.resolve(1);
const p2 = Promise.resolve(Promise.resolve(2));
const p3 = Promise.resolve(Promise.reject(3));
const p4 = new Promise((resolve) => {
setTimeout(() => {
resolve(4);
}, 1000);
});
Promise.all([p4, p1, p2]).then(
(value) => {
console.log('res1 value:', value);
},
(reason) => {
console.log('res1 reason:', reason);
},
);
Promise.all([p1, p2, p3, p4]).then(
(value) => {
console.log('res2 value:', value);
},
(reason) => {
console.log('res2 reason:', reason);
},
);
Promise.race([p4, p1, p3, p2]).then(
(value) => {
console.log('res3 value:', value);
},
(reason) => {
console.log('res3 reason:', reason);
},
);
/* 执行结果
res2 reason: 3
res3 value: 1
res1 value: [ 4, 1, 2 ]
*/
实现的大致思路如下:
const pAll = (promises) => {
// 保存所有成功结果的数组
const values = [];
// 成功的次数
let successCount = 0;
// 返回一个promise对象
return new Promise((resolve, reject) => {
// 遍历异步任务数组
promises.forEach((p, index) => {
/**
* 这里用 Promise.resolve()包装一下p是考虑promises中的值有可能不是promise对象,
* 例如普通的值 pAll([p1, p2, 2, 'hello'])
*/
Promise.resolve(p).then(
(value) => {
/**
* 注意这里不要用 values.push(value) 这种方式来将成功的值放到数组中
* 由于promises数组中的异步任务并不一定是按顺序完成的
* 应该使用 values[index] = value 这种方式
*/
values[index] = value;
successCount += 1;
// 当成功的次数等于promises异步任务数组的长度时,将最终的结果resolve出去
if (successCount === promises.length) {
resolve(values);
}
},
(reason) => {
// 当遇到一个异步任务失败的时候,直接reject即可,后续的任务再失败就不用考虑了
reject(reason);
},
);
});
});
};
可以测试一下我们实现的代码:
pAll([p4, p1, p2]).then(
(value) => {
console.log('res value:', value);
},
(reason) => {
console.log('res reason:', reason);
},
);
/* 执行结果
res value: [ 4, 1, 2 ]
*/
promise.race的实现相对来说就更简单一些了。
const pRace = (promises) => {
return new Promise((resolve, reject) => {
promises.forEach((p) => {
p.then(
(value) => {
resolve(p);
},
(reason) => {
reject(reason);
},
);
});
});
};
同样测试一下代码:
pRace([p4, p1, p3, p2]).then(
(value) => {
console.log('value:', value);
},
(reason) => {
console.log('reason:', reason);
},
);
/* 执行结果
value: 1
*/