问题描述
我有1000条记录需要访问速率受限的API端点。我想这样做,以便在任何给定时间只有5次调用URL,这样我就不会同时发出1000个请求。我怎样才能做到这一点?我有以下内容:
I have 1000 records that need to hit an API endpoint that is rate limited. I want to make it so that there is only 5 calls on the URL at any given time so that I am not making 1000 requests simultaneously. How can I do this? I have the following:
var Promise = require("bluebird");
var geocoder = Promise.promisifyAll(require('geocoder'));
var fs = require('fs');
var async = require('async');
var parse = require('csv-parse/lib/sync');
var inputFile = './myaddresses.txt'
var file = fs.readFileSync(inputFile, "utf8");
var records = parse(file, {columns: true});
var promises = [];
for(var i = 0; i < records.length; i++) {
var placeName = records[i]['Place Name'];
promises.push(geocoder.geocodeAsync(placeName));
}
Promises.all(promises).then(function(result) {
result.forEach(function(geocodeResponse) {
console.log(geocodeResponse);
})
}
推荐答案
要限制一次传入的并发请求数,我建议使用Bluebird的 Promise.map()
,它提供并发选项。它将完成所有操作以下内容适用于您:
To limit the number of concurrent requests that are in-flight at once, I'd recommend using Bluebird's Promise.map()
which offers a concurrency option. It will do all of the following for you:
- 迭代您的数组
- 限制并发请求的数量您将并发选项设置为
- 在最终结果数组中按顺序收集所有结果
以下是如何使用它:
const Promise = require('bluebird');
Promise.map(records, r => {
let placeName = r['Place Name'];
return geocoder.geocodeAsync(placeName));
}, {concurrency: 5}).then(results => {
// all results here
}).catch(err => {
// process error here
});
注意:速率限制通常与并发请求的数量通常不完全相同。限制并发请求的数量将使您更有可能保持在速率限制之下,但不会保证。有特定的速率限制模块可以更直接地管理速率限制。
Note: Rate limiting is not usually strictly the same as number of concurrent requests. Limiting the number of concurrent requests will make it more likely that you stay under a rate limit, but won't guarantee it. There are specific rate limiting modules that can manage to a rate limit more directly.
您可以为每个请求添加延迟使用Bluebird的 .delay()
。
You can add a delay to each request using Bluebird's .delay()
.
const Promise = require('bluebird');
Promise.map(records, r => {
let placeName = r['Place Name'];
return geocoder.geocodeAsync(placeName)).delay(500);
}, {concurrency: 5}).then(results => {
// all results here
}).catch(err => {
// process error here
});
处理某些类型费率的经典算法限制称为。
如果你的限制是50个请求/秒,那么你可以确保你的并发数乘以你的延迟值永远不会超过50 /秒。
If your limit is 50 requests/sec, then you can just make sure that your concurrency number times your delay value never allows more than 50/sec.
这篇关于如何制作它以便我可以在javascript中一次执行说10个承诺以防止api调用的速率限制?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!