Promise.all 使用、原理實現及錯誤處理
阿新 • • 發佈:2022-06-01
一、Promise概念
Promise是JS非同步程式設計中的重要概念,非同步抽象處理物件,是目前比較流行Javascript非同步程式設計解決方案之一。Promise.all()接受一個由promise任務組成的陣列,可以同時處理多個promise任務,當所有的任務都執行完成時,Promise.all()返回resolve,但當有一個失敗(reject),則返回失敗的資訊,即使其他promise執行成功,也會返回失敗。和後臺的事務類似。和rxjs中的forkJoin方法類似,合併多個 Observable 物件 ,等到所有的 Observable 都完成後,才一次性返回值。
二、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) })
三、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)
})
四、Promise.all錯誤處理
有時候我們使用Promise.all()執行很多個網路請求,可能有一個請求出錯,但我們並不希望其他的網路請求也返回reject,要錯都錯,這樣顯然是不合理的。如何做才能做到promise.all中即使一個promise程式reject,promise.all依然能把其他資料正確返回呢?
1、全部改為序列呼叫(失去了node 併發優勢)
2、當promise捕獲到error 的時候,程式碼吃掉這個異常,返回resolve,約定特殊格式表示這個呼叫成功了
var p1 =new Promise(function(resolve,reject){
setTimeout(function(){
resolve(1);
},0)
});
var p2 = new Promise(function(resolve,reject){
setTimeout(function(){
resolve(2);
},200)
});
var p3 = new Promise(function(resolve,reject){
setTimeout(function(){
try{
console.log(XX.BBB);
}
catch(exp){
resolve("error");
}
},100)
});
Promise.all([p1, p2, p3]).then(function (results) {
console.log("success")
console.log(results);
}).catch(function(r){
console.log("err");
console.log(r);
});