Javascript 承诺使用速率限制器的回调
我正在从事一个项目,在这个项目中,我必须遍历几个api,并在每个api上下载多个页面。我有使用回调的代码,但我不确定如何在最后一个http请求完成后运行代码Javascript 承诺使用速率限制器的回调,javascript,node.js,promise,Javascript,Node.js,Promise,我正在从事一个项目,在这个项目中,我必须遍历几个api,并在每个api上下载多个页面。我有使用回调的代码,但我不确定如何在最后一个http请求完成后运行代码 const RateLimiter = require('limiter').RateLimiter; const limiter = new RateLimiter(1, 'second'); request(url,{json:true}function(err,res,body){ let bunchOfURLs = bod
const RateLimiter = require('limiter').RateLimiter;
const limiter = new RateLimiter(1, 'second');
request(url,{json:true}function(err,res,body){
let bunchOfURLs = body['bunchOfURLs'];
for(let i = 0; i < bunchOfURLs.length;i++){
limiter.removeTokens(1,function(){
request(bunchOfURLs[i],{json:true},function(err2,res2,body2){
let moreURLs = body2['moreURLs'];
for(let j = 0; j < moreURLs.length;j++){
request(moreURLs[j],function(err3,res3,body3){
// Once all downloads are done console.log('Done!')
});
}
});
}
}
});
如果您计划将
Promises
与limiter
模块一起使用,那么您可能需要创建一个简单的包装器方法来删除令牌。最好使用请求承诺
模块,或者创建另一个简单的包装器来发出请求
看起来是这样的:
function removeTokens(tokens) {
return new Promise((resolve) => {
limiter.removeTokens(tokens, resolve);
});
}
request(url, {json: true}).then((body) => {
let promises = body['bunchOfURLs'].map((url2) => {
return removeTokens(1).then(() => {
return request(url2, {json:true}).then((body2) => {
let promises2 = body2['moreURLs'].map((url3) => {
return request(url3);
});
return Promise.all(promises2);
});
});
});
return Promise.all(promise);
});
如果您选择创建一个简单的包装而不是请求承诺
:
function requestJSON(url) {
return Promise((resolve, reject) => {
request(url, {json: true}, (err, res, body) => {
if (err) {
reject(err);
} else {
resolve(body);
}
});
});
}
后续编辑。您可以通过捕获错误并再次执行请求来处理“重试”
requestJSON(url).catch((err) => {
if (err.code === 'ECONNTIMEOUT' || err.code === 'ECONNRESET') {
return requestJSON(url)
} else {
return Promise.reject(err);
}
});
您可能需要添加一些逻辑,以便在一段时间后停止,否则这可能会导致一个无限循环。
对于利率限制器,我认为不会添加嵌套的承诺
不是限制器
造成这种情况,而是异步代码需要您的答案。出于好奇,在您提供的示例包装器上,您将如何处理错误重试(EconTimeout、EconReset等)。如果(err)返回requestJSON(url),您是否需要代码>?不,这将吞掉错误。我将对答案进行编辑。
requestJSON(url).catch((err) => {
if (err.code === 'ECONNTIMEOUT' || err.code === 'ECONNRESET') {
return requestJSON(url)
} else {
return Promise.reject(err);
}
});