2017-05-31 66 views
0

我試圖使用request-promise模塊來檢查多個網站。如果按照設計使用Promise.all,承諾將首先拒絕。執行多個請求任務並等待所有請求完成是否被完成或拒絕的正確方法是什麼?我已經提出了以下兩個功能。使用多個請求並承諾

CheckSitesV1由於拒絕承諾而返回異常。然而CheckSitesV2等待所有承諾完成,無論它們是被滿足還是被拒絕。如果您能評論我寫的代碼是否合理,我將不勝感激。我使用的NodeJS V7.9.0

const sitesArray = ['http://www.example.com','https://doesnt-really-exist.org','http://www.httpbin.org']; 

async function CheckSitesV1() { 
    let ps = []; 
    for (let i = 0; i < sitesArray.length; i++) { 
     let ops = { 
      method: 'GET', 
      uri:sitesArray[i], 
     }; 
     const resp = await rp.get(ops); 
     ps.push(resp); 
    } 
    return Promise.all(ps) 
} 

function CheckSitesV2() { 
    let ps = []; 
    for (let i = 0; i < sitesArray.length; i++) { 
     let ops = { 
      method: 'GET', 
      uri:sitesArray[i], 
     }; 
     ps.push(rp.get(ops)); 
    } 
    return Promise.all(ps.map(p => p.catch(e => e))) 
} 

CheckSitesV1().then(function (result) { 
    console.log(result); 
}).catch(function (e) { 
    console.log('Exception: ' + e); 
}); 

CheckSitesV2().then(function (result) { 
    console.log(result); 
}).catch(function (e) { 
    console.log('Exception: ' + e); 
}); 
+0

「正確」 的方式是不完全相同的方式你想要發生什麼。 'CheckSitesV1'並不解決並行的承諾,而'CheckSitesV2'。你想要哪種行爲? –

+0

我想檢查所有網站是否可以達到它。當其中一個請求失敗時,CheckSitesV1返回被拒絕。我不知道'CheckSitesV2'是否遵循最佳實踐。我並沒有完全在JS – Meanteacher

+0

中獲得異步等待,但是您希望並行或串行執行請求嗎?因爲這就是這兩個解決方案之間的區別。另外,我不相信第一個實際上不會做你想做的事。只要承諾被拒絕,'CheckSitesV1'就會拋出:https://jsfiddle.net/gbw0c7x1/ –

回答

1

function CheckSitesV2() { 
    let ps = []; 
    for (let i = 0; i < sitesArray.length; i++) { 
     let ops = { 
      method: 'GET', 
      uri:sitesArray[i], 
     }; 
     ps.push(rp.get(ops)); 
    } 
    return Promise.all(ps.map(p => p.catch(e => e))) 
} 

完全是罰款。我只能建議重構位的可讀性:

function CheckSitesV2() { 
 
    let ps = sitesArray 
 
    .map(site => rp.get({method: 'GET', uri: site}).catch(e => e)); 
 

 
    return Promise.all(ps); 
 
}

關於異步試試這個

async function CheckSitesV1() { 
 
    let results = []; 
 
    for (let i = 0; i < sitesArray.length; i++) { 
 
     let opts = { 
 
      method: "GET", 
 
      uri: sitesArray[i] 
 
     }; 
 
     const resp = await rp.get(opts).catch(e => e); 
 
     results.push(resp); 
 
    } 
 
    return results; 
 
} 
 

 
CheckSitesV1().then(console.log)

+0

雖然'async' /'await'大多數人可能會使用'try'-'catch'。即使它比'.catch()':-)更奇怪也更臃腫 – Bergi

+0

@Bergi'catch(e => e)'的全部目的是抑制錯誤並將它傳遞給下一個成功的'then'作爲定期的結果。 –

+0

當然可以,但你也可以'try {results.push(await rp.get(opts)); } catch(e){results.push(e); }(我認爲這會比較習慣,即使我不喜歡它) – Bergi