对于node.js,我想http.get
一些远程网址,一次只能运行10个(或n个)。
我还想在本地发生异常(m次)时重试请求,但是当状态代码返回错误(5XX,4XX等)时,请求计为有效。
这对我来说真的很难理解。
问题:
似乎建议使用promises的每个异步问题,但我最终嵌套了太多的承诺,很快就变得无法修复。
答案 0 :(得分:4)
有很多方法可以同时处理10个请求。
异步库 - 将异步库与.parallelLimit()
method一起使用,您可以在其中指定一次要运行的请求数。
蓝鸟承诺库 - 使用Bluebird promise library和request
库将http.get()
包装成可以返回承诺然后使用的内容Promise.map()
并发选项设置为10
。
手动编码 - 手动编码您的请求以启动10,然后每次完成,启动另一个。
在所有情况下,您都必须手动编写一些重试代码,并且与所有重试代码一样,您必须非常仔细地确定您重试的错误类型,重试时间,重试次数之间的退避量。当你最终放弃时(所有你没有指定的东西)。
其他相关答案:
How to make millions of parallel http requests from nodejs app?
Million requests, 10 at a time - manually coded example
我首选的方法是Bluebird和promises。包括按顺序重试和结果收集,可能看起来像这样:
const request = require('request');
const Promise = require('bluebird');
const get = Promise.promisify(request.get);
let remoteUrls = [...]; // large array of URLs
const maxRetryCnt = 3;
const retryDelay = 500;
Promise.map(remoteUrls, function(url) {
let retryCnt = 0;
function run() {
return get(url).then(function(result) {
// do whatever you want with the result here
return result;
}).catch(function(err) {
// decide what your retry strategy is here
// catch all errors here so other URLs continue to execute
if (err is of retry type && retryCnt < maxRetryCnt) {
++retryCnt;
// try again after a short delay
// chain onto previous promise so Promise.map() is still
// respecting our concurrency value
return Promise.delay(retryDelay).then(run);
}
// make value be null if no retries succeeded
return null;
});
}
return run();
}, {concurrency: 10}).then(function(allResults) {
// everything done here and allResults contains results with null for err URLs
});
答案 1 :(得分:1)
简单的方法是使用async
库,它有一个.parallelLimit
方法,可以完全满足您的需求。