1. 程式人生 > 其它 >Promise.all 使用、原理實現及錯誤處理

Promise.all 使用、原理實現及錯誤處理

一、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);
});