使用 node.js,我想http.get
多个远程 url,一次只运行 10(或 n)个。
如果本地发生异常(m 次),我也想重试请求,但是当状态代码返回错误(5XX、4XX 等)时,请求被视为有效。
这对我来说真的很难理解。
问题:
- 无法 try catch http.get,因为它是异步的。
- 需要一种在失败时重试请求的方法。
- 我需要某种信号量来跟踪当前事件的请求计数。
- 当所有请求完成后,我想在一个列表中获取所有请求 url 和响应状态代码的列表,我想对其进行排序/分组/操作,因此我需要等待所有请求完成。
似乎每个异步问题都建议使用 promises,但我最终嵌套了太多的 promises,它很快变得无法加密。
最佳答案
有很多方法可以处理同时运行 10 个请求。
异步库 - 将异步库与
.parallelLimit()
method 一起使用您可以在其中指定一次要运行的请求数。Bluebird Promise 库 - 使用 Bluebird promise library和
request
库将您的http.get()
包装成可以返回 promise 的东西,然后使用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
});
关于javascript - 运行 1000 个请求,以便一次只运行 10 个,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39141614/