在Node.js中限制请求

时间:2012-09-24 19:37:08

标签: javascript node.js settimeout throttling

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

data.forEach(function (result, i) {

     url = data[i].url;

     request(url);

});

请求函数正在向给定的URL发出http请求。 但是,同时提出所有这些请求会导致各种各样的问题。

所以我认为我应该通过引入某种计时器来减慢速度。

但我不知道如何将forach循环与setTimeOut / setInterval结合起来

请注意我在服务器(nodejs)而不是浏览器上执行此操作。

谢谢你的帮助。

6 个答案:

答案 0 :(得分:7)

由于您的问题是全局问题,因此您应该使用全局静态计数器调整request函数,以便一次只运行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);
}

答案 1 :(得分:5)

data.forEach(function (result, i) {

     url = data[i].url;

     setTimeout(
         function () {
              request(url);
         }, 
         1000 * (i + 1) // where they will each progressively wait 1 sec more each
     );

 });

答案 2 :(得分:3)

而不是setTimeout可以让它们按顺序运行。我假设您的callback函数有一个request()参数。

function makeRequest(arr, i) {
    if (i < arr.length) {
        request(arr[i].url, function() { 
                                i++; 
                                makeRequest(arr, i); 
                            });
    }
}

makeRequest(data, 0);

如果您需要更多时间请求,请将setTimeout添加到回调中。

function makeRequest(arr, i) {
    if (i < arr.length) {
        request(arr[i].url, function() { 
                                i++; 
                                setTimeout(makeRequest, 1000, arr, i); 
                            });
    }
}

makeRequest(data, 0);

答案 3 :(得分:1)

您可以使用setTimeout延迟通话。以下代码将确保每个请求在其先前请求的timerMultiPlier毫秒后调用。

var timerMultiPlier = 1000;
data.forEach(function (result, i) {
     setTimeout(function(){
           url = data[i].url;         
           request(url);
   }, timerMultiPlier*i );

});

答案 4 :(得分:0)

您可以通过索引来抵消每个项目的执行延迟,如下所示:

data.forEach(function (result, i) { 
  setTimeout(function() {
    url = data[i].url; 
    request(url);
  }, i * 100);
}); 

这将使每次迭代在前一次迭代后执行约100毫秒。您可以将100更改为您想要更改延迟的任何数字。

答案 5 :(得分:0)

上述许多解决方案虽然适用于少数几个请求,但在处理成千上万个请求时,会不可避免地扼杀和整理页面。不是将所有定时器排在一个,而是应该依次对每个定时器进行排序。如果您的目标是拥有漂亮而又蓬松的代码以及大量的糖和“好东西”,那么下面就是您的解决方案。

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;
                }
            })();
        }
    };
}

漂亮,漂亮,蓬松的糖衣用途:

onceEvery(
    miliseconds( 150 )
).doForEach(
    ["Lorem", "ipsum", "dolar", "un", "sit", "amet"],
    function(value, index, array){
        console.log( value, index );
    }
)

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;
                }
            })();
        }
    };
}