简体   繁体   English

Node.js - 使用每秒5个请求的API限制

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM