Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to use setInterval function within for loop

I'm trying to run multiple timers given a variable list of items. The code looks something like this:

var list = Array(...);  for(var x in list){     setInterval(function(){         list[x] += 10;         console.log(x + "=>" + list[x] + "\n");     }, 5 * 1000); } 

The problem with the above code is that the only value being updated is the item at the end of the list, multiplied by the number of items in the list.

Can anyone offer a solution and some explanation so I know why it's behaving this way?

like image 950
hyleaus Avatar asked Oct 13 '11 03:10

hyleaus


People also ask

How do you use set intervals in a for loop?

In setInterval we use the method clearInterval and pass in the variable that contains the ID of the interval that we wish to stop. To do this we set the condition in which to exit the loop inside the setInterval callback function.

How do you stop an interval in a for loop?

Answer: Use the clearInterval() Method You can pass this interval ID to the global clearInterval() method to cancel or stop setInterval() call.

Can we use setTimeout in for loop?

The setTimeout function callback isn't triggered until the for loop execution has completed. When the for loop has finished executing the value of i is 5. Now when the setTimeout call begins to execute it uses the last set value of i which is 5. Hence 5 is printed in all the setTimeout callbacks.

Can you clearInterval within setInterval?

Calling clearInterval() inside setInterval() has no effect But after calling clearInterval(), it will continue to execute.


1 Answers

So, a few things:

  1. Most importantly, the callback function you've passed to setInterval() maintains a reference to x rather than the snapshot value of x as it existed during each particular iteration. So, as x is changed in the loop, it's updated within each of the callback functions as well.
  2. Additionally, for...in is used to enumerate object properties and can behave unexpectedly when used on arrays.
  3. What's more, I suspect you really want setTimeout() rather than setInterval().

You can pass arguments to your callback function by supplying additional arguments to setTimout():

var timeoutID = window.setTimeout(func, delay, [param1, param2, ...]);

Numbers will be passed by value rather than reference. Here's an example:

var list = [1,2,3,4];    for (var x = 0, ln = list.length; x < ln; x++) {    setTimeout(function(y) {          console.log("%d => %d", y, list[y] += 10);    }, x * 500, x); // we're passing x  }
like image 76
canon Avatar answered Oct 16 '22 05:10

canon