我有一个'脚本'这会对特定API执行数千次请求。这个API每秒只允许5个请求(可能它的测量方式与我不同)。要使用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()
一旦大约300个请求(发出或接受)短时间内被触发,这些请求就会开始相互干扰。有没有人有更好的解决方案?我认为对这个函数的递归调用会有所帮助,而且确实如此,但它并没有解决问题。也许有一种模式可以对请求进行排队,并且一次只能执行一些操作?或许图书馆?
谢谢!
答案 0 :(得分:3)
我的代码将运行TimedQueue
,只要他们的工作要完成。所有工作完成后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');
});
&#13;
答案 1 :(得分:3)
好的,不是递归调用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();
答案 2 :(得分:-1)
我不确定,但也许你从下面得到一些想法
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>