Javascript 限制Node.js中的请求
我有一个数组。我可以用foreach方法循环它Javascript 限制Node.js中的请求,javascript,node.js,settimeout,throttling,Javascript,Node.js,Settimeout,Throttling,我有一个数组。我可以用foreach方法循环它 data.forEach(function (result, i) { url = data[i].url; request(url); }); 请求函数向给定url发出http请求。 然而,同时提出所有这些要求会导致各种各样的问题 所以我想我应该通过引入一些定时器来放慢速度 但我不知道如何将forach循环与setTimeOut/setInterval结合起来 请注意,我是在服务器上(nodejs)而不是在浏览器上执行
data.forEach(function (result, i) {
url = data[i].url;
request(url);
});
请求函数向给定url发出http请求。
然而,同时提出所有这些要求会导致各种各样的问题
所以我想我应该通过引入一些定时器来放慢速度
但我不知道如何将forach循环与setTimeOut/setInterval结合起来
请注意,我是在服务器上(nodejs)而不是在浏览器上执行此操作的
谢谢您的帮助。您可以使用setTimeout延迟通话。下面的代码将确保每个请求在其上一个请求的
timerMultiPlier
毫秒后被调用
var timerMultiPlier = 1000;
data.forEach(function (result, i) {
setTimeout(function(){
url = data[i].url;
request(url);
}, timerMultiPlier*i );
});
您可以通过索引来抵消每个项的执行延迟,如下所示:
data.forEach(function (result, i) {
setTimeout(function() {
url = data[i].url;
request(url);
}, i * 100);
});
这将使每次迭代在上一次迭代后大约100毫秒执行。您可以将
100
更改为您想要更改延迟的任何数字。而不是setTimeout
可以让它们按顺序运行。我假设您的request()
函数中有一个回调
参数
function makeRequest(arr, i) {
if (i < arr.length) {
request(arr[i].url, function() {
i++;
makeRequest(arr, i);
});
}
}
makeRequest(data, 0);
由于您的问题是全局性的,您应该调整
请求
函数,使其一次仅运行5个请求-使用全局静态计数器。如果你的请求是在
function request(url, callback) {
ajax(url, callback);
}
var count = 0;
var waiting = [];
function request(url, callback) {
if (count < 5) {
count++;
ajax(url, function() {
count--;
if (waiting.length)
request.apply(null, waiting.shift());
callback.apply(this, arguments);
});
} else
waiting.push(arguments);
}
现在使用类似于
function request(url, callback) {
ajax(url, callback);
}
var count = 0;
var waiting = [];
function request(url, callback) {
if (count < 5) {
count++;
ajax(url, function() {
count--;
if (waiting.length)
request.apply(null, waiting.shift());
callback.apply(this, arguments);
});
} else
waiting.push(arguments);
}
var计数=0;
var等待=[];
函数请求(url、回调){
如果(计数小于5){
计数++;
ajax(url,函数(){
计数--;
如果(等待长度)
request.apply(null,waiting.shift());
apply(这个,参数);
});
}否则
等待。推送(参数);
}
上述许多解决方案虽然适用于少数请求,但在处理数以万计的请求时却会毫无顾忌地阻塞页面。不要一次排队等待所有计时器,每个计时器应该一个接一个地按顺序排队。如果你的目标是有一个很好的,非常蓬松的代码,里面有很多糖和糖果,那么下面就是你的解决方案
function miliseconds(x) { return x }
function onceEvery( msTime ){
return {
doForEach: function(arr, eachF){
var i = 0, Len = arr.length;
(function rekurse(){
if (i < Len) {
eachF( arr[i], i, arr );
setTimeout(rekurse, msTime);
++i;
}
})();
}
};
}
函数毫秒(x){return x}
函数onceEvery(msTime){
返回{
doForEach:函数(arr、eachF){
var i=0,Len=arr.length;
(函数rekurse(){
如果(i
漂亮、蓬松的糖衣用法:
onceEvery(
毫秒(150)
)多弗雷奇先生(
[“Lorem”、“ipsum”、“dolar”、“un”、“sit”、“amet”],
函数(值、索引、数组){
console.log(值、索引);
}
)
函数毫秒(x){return x}
函数onceEvery(msTime){
返回{
doForEach:函数(arr、eachF){
var i=0,Len=arr.length;
(函数rekurse(){
如果(i }
不完全是您想要的,但您可以尝试排队:。IE一次只做10个请求。你说的“各种各样的问题”是什么意思?@Bergi在我自己的nodejs服务器上,任何“代理”都可以发出5个请求的默认限制。我可以增加,但我不想这样做。对于外部服务器,如果您发出大量并发请求,它们会切断您的连接。这就是我所说的“所有类型的问题”的意思。@saeed:yourrequest()
函数接受回调吗。如果是这样,您不需要设置超时来处理5个请求限制。只需按顺序运行它们,在上一个完成后执行下一个。@user1689607的意思是在收到http响应后继续执行。我认为这比设置计时器要复杂得多。