2017-05-31 89 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