Multiple setTimout’s with a delay in between

Maxim van Veen
08-08-2017

Imagine that you have to loop though thirty item, products on a webshop for example. And you have to do a request for every product.
You’re only allowed to do 10 requests per second. What would happen when you run this code?

    var thirtyItems = document.getElementsByClassName('one-of-thirty');
    for (var i = 0; i < thirtyItems.length; i++) {
        // Request to server
    }

The result of this is that you’ll get a ‘Too many requests’ response and the script stops executing.
So this is not going to work, but how are you going to solve this problem?

You could fix this problem with a setTimeout function. Set a delay between the requests with a setTimeout so that you won’t get too many requests.

The first thing you need to know is that we’re not using variable i for this. The reason is that we’re counting one up with i for every time we’re going through the for loop. And because we’re using a setTimeout the counter is going faster than that our script runs, so we’re not getting the right element this way.
So we’re making a counter for our script. In this case I’ll call it nthItem. Each time we are doing a request we’re going to count one up by our variable. Make sure you do this inside the setTimeout function.
By doing this we avoid that the counter is on 30 while we need to get for example the 4th element.

As shown below is what our code looks like on the moment. So if we run this code, would it work?

    var thirtyItems = document.getElementsByClassName('one-of-thirty');
    var nthItem = 0;
    for (var i = 0; i < thirtyItems.length; i++) {
        setTimeout(function() {
            // Request to server
            nthItem++;
        }, 100);
    }

The answer is no. We’re on the right way but the problem is that our for loop is going fast and all the setTimeouts are started at the same time. So the time that the function waits before executing is the same for every item.
What we need to have is a delay between the setTimeouts. The for loop is not going slower by putting a setTimeout inside it. So we need to make the time for the setTimeout function bigger every time we loop through the for loop.
We do this by putting the value of the time that we use for the setTimeout inside a variable and every time we loop through the for loop we’re counting the same amount of time by the current time inside the variable.
So let’s say we’re declaring a variable time and make it 100. And every time we loop we’re counting 100 up by the current value, so the first time time is 100, the second time it is 200, the third time is 300 etc.
Make sure that you’re adding an amount of time to our variable outside the setTimeout. Otherwise we still have the same issue.
By doing this there is a delay of 100 milliseconds between every time a setTimeout function is executing.
So this is what our code looks like.

    var thirtyItems = document.getElementsByClassName('one-of-thirty');
    var nthItem = 0;
    var time = 100;
    for (var i = 0; i < thirtyItems.length; i++) {
        setTimeout(function() {
            // Request to server
            nthItem++;
        }, time);
        time = time + 100;
    }

And this is the way you can set a setTimeout inside a for loop with a delay between every time the next timeout function executes.

LEAVE A REPLY

you might also like