我在一个项目中工作,我需要通过 API 发出请求。请求返回有关支持票的数据,但问题是我有大约 500 张票要获取有关数据,每张票都需要一个请求。为了加快请求速度,我尝试构建一个同时生成许多请求的异步例程。但是,由于我正在集成的 API 具有每秒 10 个请求的速率限制器,因此一些例程得到的答案是“超出限制”。如果我按顺序发出请求,大约需要 5 分钟。
那样的话,有人可以为我提供有关该任务的提示吗?我尝试了一些解决方案,比如 NodeJS 的 rate-limiter,但它只是同时生成 10 个请求,并且没有给出任何类型的错误处理或请求失败重试。
关于语言,它没有限制,该项目是用NodeJS编写的,但也有一些python代码,集成其他语言没有问题。
最佳答案
自己创建这样的东西并不难,而且它会给你所需的灵 active 。
有一些奇特的方法,比如跟踪每个的开始和完成时间,并检查你是否在第二个发送了 10 个。
系统可能还会将其限制为 10 个事件请求(即,您不能启动 100 个请求,每秒 10 个,然后让它们全部处理)。
如果您这样假设,我会说一次启动 10 个,然后让它们完成,然后启动下一批。您也可以启动 10 个,然后在每次完成时再启动 1 个。您可以将其视为“thread pool”。
您可以通过一个简单的变量来轻松跟踪这一点,该变量会跟踪正在进行的调用次数。然后,只需检查每秒进行一次调用的次数(以避免 1 秒的限制),如果您有可用的“线程”,则触发更多的新请求。
它可能看起来像这样:
const threadLimit = 10;
const rateLimit = 1000; // ms
let activeThreads = 0;
const calls = new Array(100).fill(1).map((_, index) => index); // create an array 0 through 99 just for an example
function run() {
if (calls.length == 0) {
console.log('complete');
return;
}
// threadLimit - activeThreads is how many new threads we can start
for (let i = 0; i < threadLimit - activeThreads && calls.length > 0; i++) {
activeThreads++; // add a thread
call(calls.shift())
.then(done);
}
setInterval(run, rateLimit);
}
function done(val) {
console.log(`Done ${val}`);
activeThreads--; // remove a thread
}
function call(val) {
console.log(`Starting ${val}`);
return new Promise(resolve => waitToFinish(resolve, val));
}
// random function to simulate a network call
function waitToFinish(resolve, val) {
const done = Math.random() < .1; // 10% chance to finish
done && resolve(val)
if (!done) setInterval(() => waitToFinish(resolve, val), 10);
return done;
}
run();
基本上,run()
会根据限制和已完成的数量启动尽可能多的新线程。然后,它每秒重复该过程,尽可能添加新的。
您可能需要尝试使用 threadLimit
和 rateLimit
值,因为大多数速率限制系统实际上不会让您达到限制并且不会完成后立即发布。
关于javascript - 通过具有请求速率限制器的 API 进行异步请求,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50589034/