一、实现一个Promise.all方法,要求保留错误 并且解释原理
1.Promise概念
Promise是JS异步编程中的重要概念,异步抽象处理对象,是目前比较流行Javascript异步编程解决方案之一。Promise.all()接受一个由promise任务组成的数组,可以同时处理多个promise任务,当所有的任务都执行完成时,Promise.all()返回resolve,但当有一个失败(reject),则返回失败的信息,即使其他promise执行成功,也会返回失败。和后台的事务类似。和rxjs中的forkJoin方法类似,合并多个 Observable 对象 ,等到所有的 Observable 都完成后,才一次性返回值。
2. Promise.all如何使用
对于 Promise.all(arr) 来说,在参数数组中所有元素都变为决定态后,然后才返回新的 promise。
// 以下 demo,请求两个 url,当两个异步请求返还结果后,再请求第三个 url
const p1 = request(`http://some.url.1`)
const p2 = request(`http://some.url.2`)
Promise.all([p1, p2])
.then((datas) => { // 此处 datas 为调用 p1, p2 后的结果的数组
return request(`http://some.url.3?a=${datas[0]}&b=${datas[1]}`)
})
.then((data) => {
console.log(msg)
})
3、Promise.all原理实现
function promiseAll(promises){
return new Promise(function(resolve,reject){
if(!Array.isArray(promises)){
return reject(new TypeError("argument must be anarray"))
}
var countNum=0;
var promiseNum=promises.length;
var resolvedvalue=new Array(promiseNum);
for(var i=0;i<promiseNum;i++){
(function(i){
Promise.resolve(promises[i]).then(function(value){
countNum++;
resolvedvalue[i]=value;
if(countNum===promiseNum){
return resolve(resolvedvalue)
}
},function(reason){
return reject(reason)
)
})(i)
}
})
}
var p1=Promise.resolve(1),
p2=Promise.resolve(2),
p3=Promise.resolve(3);
promiseAll([p1,p2,p3]).then(function(value){
console.log(value)
})
4、Promise.all错误处理
有时候我们使用Promise.all()执行很多个网络请求,可能有一个请求出错,但我们并不希望其他的网络请求也返回reject,要错都错,这样显然是不合理的。如何做才能做到promise.all中即使一个promise程序reject,promise.all依然能把其他数据正确返回呢?
1、为每个promise关联一个错误的处理函数
var p1 = Promise.resolve(3).catch(function(err) {
return err;
});
var p2 = Promise.reject(2).catch(function(err) {
return err;
});
var p3 = new Promise((resolve, reject) => {
setTimeout(resolve, 100, "foo");
}).catch(function(err) {
return err;
});
Promise.all([p1, p2, p3]).then(values => {
console.log(values); // [3, 2, "foo"]
}).catch(function(err) {
console.log(1); //不会走到这里
});
自我理解: 之所以每一个promise都加了catch后就可以继续执行,原因就在于promise的链式编程特点,同理在promise.race里 加上catch后,亦可继续执行then中代码模块。
总结:在promise中,.catch()函数会捕获promise内的throw错误和reject抛出的错误。
如果promise发生异常,而没有.catch()函数,也会在控制台抛出异常,但后面的代码依旧会执行。
2、Promise.all中的错误处理(转于慕课)
https://blog.csdn.net/weixin_44038264/article/details/118888977?utm_medium=distribute.pc_relevant.none-task-blog-2defaultbaidujs_title~default-0-118888977-blog-125160408.pc_relevant_multi_platform_whitelistv3&spm=1001.2101.3001.4242.1&utm_relevant_index=3