[英]Node.js - Working with an API limit of 5 requests per second
I've got a 'script' that does thousands of requests to a specific API. 我有一个“脚本”,可以对特定的API执行数千个请求。 This API will only allow 5 requests per second (and probably it measures differently then me). 这个API每秒只允许5个请求(可能它的测量方式与我不同)。 To make the requests I'm using request-promise
framework, and I've superseded the normal request-promise
function with this: 为了发出请求,我正在使用request-promise
框架,并且我已经取代了正常的request-promise
函数:
const request_promise = require('request-promise')
function waitRetryPromise() {
var count = 0 // keeps count of requests
function rp(options) {
const timedCall = (resolve) => setTimeout( ()=>resolve(rp(options)),1000) // recursive call
count += 1
if (count % 3 == 0) { // recalls after a second on every third request
return new Promise(timedCall)
} else {
return request_promise(options)
}
}
return rp
}
const rp = waitRetryPromise()
Once around 300 requests (give or take) are fired off in short succession, these requests start to interfere with each other. 一旦大约300个请求(给予或接受)短时间内被触发,这些请求就会开始相互干扰。 Does anyone have a better solution? 有没有人有更好的解决方案? I thought the recursive call to this same function would help, and It did but it didn't solve the problem. 我认为对这个函数的递归调用会有所帮助,而且确实如此,但它没有解决问题。 Maybe there is a pattern to queue requests, and do them a few at a time? 也许有一种模式可以对请求进行排队,并且一次只能执行一些操作? A library perhaps? 或许图书馆?
Thanks! 谢谢!
OK, rather than recursing the call to rp etc, just make sure you delay between requests by an appropriate amount ... for 5 per second, that's 200ms 好的,而不是递归调用rp等,只需确保在请求之间延迟适当的数量......每秒5次,即200ms
function waitRetryPromise() {
let promise = Promise.resolve();
return function rp(options) {
return promise = promise
.then(() => new Promise(resolve => setTimeout(resolve, 200)))
.then(() => request_promise(options));
}
}
const rp = waitRetryPromise();
My code will run the TimedQueue
so as long as their is work to be done. 只要他们的工作要完成,我的代码就会运行TimedQueue
。 The process()
method resolves when all work is finished: 所有工作完成后, process()
方法结算:
class Queue { constructor() { this.queue = []; } enqueue(obj) { return this.queue.push(obj); } dequeue() { return this.queue.shift(); } hasWork() { return (this.queue.length > 0); } } function t_o(delay) { return new Promise(function (resolve, reject) { setTimeout(function () { resolve(); }, delay); }); } class TimedQueue extends Queue { constructor(delay) { super(); this.delay = delay; } dequeue() { return t_o(this.delay).then(() => { return super.dequeue(); }); } process(cb) { return this.dequeue().then(data => { cb(data); if (this.hasWork()) return this.process(cb); }); } } var q = new TimedQueue(500); for (var request = 0; request < 10; ++request) q.enqueue(request); q.process(console.log).then(function () { console.log('done'); });
I am not sure but maybe you get some idea from below 我不确定,但也许你从下面得到一些想法
function placeAnOrder(orderNumber) { console.log("customer order:", orderNumber) cookAndDeliverFood(function () { console.log("food delivered order:", orderNumber); }); } // 1 sec need to cook function cookAndDeliverFood(callback){ setTimeout(callback, 1000); } //users web request placeAnOrder(1); placeAnOrder(2); placeAnOrder(3);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.