Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/455.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 限制Node.js中的请求_Javascript_Node.js_Settimeout_Throttling - Fatal编程技术网

Javascript 限制Node.js中的请求

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)而不是在浏览器上执行

我有一个数组。我可以用foreach方法循环它

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:your
request()
函数接受回调吗。如果是这样,您不需要设置超时来处理5个请求限制。只需按顺序运行它们,在上一个完成后执行下一个。@user1689607的意思是在收到http响应后继续执行。我认为这比设置计时器要复杂得多。