gpt4 book ai didi

javascript - 定时 promise 队列/节流

转载 作者:搜寻专家 更新时间:2023-11-01 04:08:38 26 4
gpt4 key购买 nike

我有一个 request-promise向 API 发出请求的函数。我受此 API 的速率限制,并且不断收到错误消息:

Exceeded 2 calls per second for api client. Reduce request rates to resume uninterrupted service.

我正在运行几个 Promise.each如果我只运行 Promise.each 的一个实例,则并行循环会导致问题一切运行良好。在这些Promise.each调用它们导致相同的功能 a 与 request-promise称呼。我想用另一个 queue 函数包装这个函数,并将间隔设置为 500 毫秒,这样就不会一个接一个地发出 request ,或并行,但设置为那个时间,在队列中。问题是我仍然需要这些 promise 来获得它们的内容,即使需要相当长的时间才能得到回应。

有什么可以帮我做这件事的吗?我可以将一个函数包装在其中,它会以设定的时间间隔响应,而不是并行响应或一个接一个地触发函数?

更新:也许它确实需要特定于 promise,我尝试使用 underscore 的 throttle 函数

var debug = require("debug")("throttle")
var _ = require("underscore")
var request = require("request-promise")

function requestSite(){
debug("request started")
function throttleRequest(){
return request({
"url": "https://www.google.com"
}).then(function(response){
debug("request finished")
})
}
return _.throttle(throttleRequest, 100)
}

requestSite()
requestSite()
requestSite()

我得到的结果是:

$ DEBUG=* node throttle.js 
throttle request started +0ms
throttle request started +2ms
throttle request started +0ms

最佳答案

更新

最后的答案是错误的,这个可行,但我仍然认为我可以做得更好:

// call fn at most count times per delay.
const debounce = function (fn, delay, count) {
let working = 0, queue = [];
function work() {
if ((queue.length === 0) || (working === count)) return;
working++;
Promise.delay(delay).tap(() => working--).then(work);
let {context, args, resolve} = queue.shift();
resolve(fn.apply(context, args));
}
return function debounced() {
return new Promise(resolve => {
queue.push({context: this, args: arguments, resolve});
if (working < count) work();
});
};
};

function mockRequest() {
console.log("making request");
return Promise.delay(Math.random() * 100);
}

var bounced = debounce(mockRequest, 800, 5);
for (var i = 0; i < 5; i++) bounced();
setTimeout(function(){
for (var i = 0; i < 20; i++) bounced();
},2000);

因此您需要在整个函数范围内限制请求 - 这很好。 Promise 几乎内置了队列。

var p = Promise.resolve(); // our queue

function makeRequest(){
p = p.then(function(){ // queue the promise, wait for the queue
return request("http://www.google.com");
});
var p2 = p; // get a local reference to the promise
// add 1000 ms delay to queue so the next caller has to wait
p = p.delay(1000);
return p2;
};

现在 makeRequest 调用将至少间隔 1000 毫秒。

jfriend 已经指出你每秒需要两个请求而不是一个 - 这与第二个队列一样容易解决:

var p = Promise.resolve(1); // our first queue
var p2 = Promise.resolve(2); // our second queue

function makeRequest(){

var turn = Promise.any([p, p2]).then(function(val){

// add 1000 ms delay to queue so the next caller has to wait
// here we wait for the request too although that's not really needed,
// check both options out and decide which works better in your case
if(val === 1){
p = p.return(turn).delay(1, 1000);
} else {
p2 = p2.return(turn).delay(1, 1000);
}
return request("http://www.google.com");
});

return turn; // return the actual promise
};

这可以推广到 n 类似地使用数组的 promise

关于javascript - 定时 promise 队列/节流,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27561158/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com