throttle requests in Node.js

I have an array. I can loop over it with the foreach method.

data.forEach(function (result, i) {

     url = data[i].url;

     request(url);

});

The request function is making a http request to the given url. However making all these requests at the same time leads to all sorts of problems.

So I thought I should slow things down by introducing some-sort of timer.

But I have no idea how will be able to combine a forach loop with setTimeOut/setInterval

Please note am doing this on the server (nodejs) rather on the browser.

Thanks for you help.

As your problem is global, you should adjust your request function to have only 5 request running at a time - using a global, static counter. If your request was before something like

function request(url, callback) {
    ajax(url, callback);
}

now use something like

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

you can delay call using setTimeout. following code will insure that each request get called after timerMultiPlier milliseconds from its previous request.

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

});

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

 });

Instead of setTimeout could have them run in sequence. I assume there's a callback parameter to your request() function.

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

makeRequest(data, 0);

If you need a little more time between requests, then add the setTimeout to the callback.

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

makeRequest(data, 0);

You can the offset the execution delay of each item by the index, like this:

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

This will make each iteration execute about 100 milliseconds after the previous one. You can change 100 to whatever number you like to change the delay.