AmD
AmD

Reputation: 1

setTimeOut within for loop

I'm confused about how to use the setTimeout function within a for loop. What I'm trying to do is highlight divs one at a time based on an array. Here's my code:

for (i = 0; i < strArray.length; i++) {
  doSetTimeout(i, colors, strArray);
}

and then the function, doSetTimeout:

function doSetTimeout(i, colors, strArray) {
  $("use." + strArray[i]).css("fill", colors[Math.floor((Math.random() * colors.length) + 1)]);
  setTimeout(function() {
    $("use").css("fill", "#333333");
  }, 1000);
}

Based on this thread, I thought having a separate function to do the color changing would solve the problem, but I'm still having an issue where all of the divs flash at the same time. Anyone know what the issue might be? And is there another, preferable way to do this?

Upvotes: 0

Views: 80

Answers (3)

trincot
trincot

Reputation: 350272

You could do it like this:

(function doSetTimeout(i, colors, strArray) {
  if (i >= strArray.length) return; // nothing more to do
  $("use." + strArray[i]).css("fill", colors[Math.floor((Math.random() * colors.length) + 1)]);
  setTimeout(function() {
    $("use").css("fill", "#333333");
    // call the function recursively
    doSetTimeout(i+1, colors, strArray);
  }, 1000);
})(0, colors, strArray); // Execute immediately for index 0

This creates a function and executes it immediately for the first element in the array.

All other calls are only done when the previous timeout event has been triggered, which will ensure a sequential processing.

The whole thing ends when all elements have been processed, since in the last call to doSetTimeout no new timeout is scheduled.

Upvotes: 4

Vahan
Vahan

Reputation: 169

Why not to use setInterval instead?

    var i = 0;        
    var intervalID = setInterval(function() {

        if (i < strArray.length) {
             $("use").css("fill", "#333333");
             $("use." + strArray[i]).css("fill", colors[Math.floor((Math.random() * colors.length) + 1)]);
             clearInterval(intervalID)
        }
        i++;
    }, 1000);

Upvotes: 0

Vad
Vad

Reputation: 4099

You can do it like this:

function doSetTimeout(i, colors, strArray) {
  if(i >= strArray.length) return;  

  $("use." + strArray[i]).css("fill", colors[Math.floor((Math.random() * colors.length) + 1)]);
  setTimeout(function() {
    $("use").css("fill", "#333333");

    doSetTimeout(i + 1, colors, strArray);
  }, 1000);
}

doSetTimeout(0, colors, strArray);

Upvotes: 0

Related Questions