-1

I have this loop. When I try pass the i with setTimeout I get a same result in each cycle " The final result of i ".

  for( var i = 0; i < step.length; i++  ){

      setTimeout( function(   ){

          insideJMove.doMove( i );

      } , 1000 ); 

    } 

How can I get different value of i inside setTimeout in each cycle ?

Mazin
  • 143
  • 1
  • 9

3 Answers3

3

Two ways you can get around this. This happens because the scope of variable defined with var is its current execution context. Making i a global variable that will be reused in your loop.

Use the let keyword:

[let] works as intended because the instances of the (anonymous) inner function [of the for loop] refer to different instances of the variable i

This is because:

Variables declared by let have as their scope the block in which they are defined, as well as in any contained sub-blocks

for( let i = 0; i < step.length; i++  ){

    setTimeout( function(   ){

        insideJMove.doMove( i );

    } , 1000 ); 

} 

or Immediately Invoked Function Expression

This creates a new execution context where the value of i stays as whatever it was when the function expression was executed.

for( var i = 0; i < step.length; i++  ){
    (function(i){
        setTimeout( function(   ){

            insideJMove.doMove( i );

        } , 1000 ); 
    })(i);

} 
pizzarob
  • 11,711
  • 6
  • 48
  • 69
1

Use let instead of var:

for (let i = 0; i < step.length; i++) {
  setTimeout(function() {
    insideJMove.doMove(i);
  } , 1000 );     
}

See What's the difference between using "let" and "var" to declare a variable?.

Community
  • 1
  • 1
Michał Perłakowski
  • 88,409
  • 26
  • 156
  • 177
0

setTimeout runs asynchronous so loop will be over when it will call first setTimeout, so variable i will has it last value in loop.

One of solutions is to use recursion:

var i=0;
function loop(){

    insideJMove.doMove( i );

    if (i<step.length)
    setTimeout(loop,1000);

    i++;
}

loop();//start our loop
Maciej Sikora
  • 19,374
  • 4
  • 49
  • 50