0

I have an example on this code:

<script>
    for(var i=1; i<3; i++){
        setTimeout(function(){
            say("HELLO NUMBER " + i);
        }, i * 2000);
    }

    function say(text){
        alert(text);
    }
</script>

And output I need is :

alert("HELLO NUMBER 1");

alert("HELLO NUMBER 2");

But in this case, I still get output :

alert("HELLO NUMBER 3");

Anyone can help for this? thanks :)

ErdeNese
  • 33
  • 7

4 Answers4

7

Classic problem with closure

for(var i=1; i<=3; i++){
    (function(num){
        setTimeout(function(){
            say("HELLO NUMBER " + num);
        }, num * 2000);

    })(i)
}

function say(text){
    alert(text);
}

Demo: Fiddle

You are using a closure variable i inside the setTimeout callback, whose value is evaluated only when the callback is executed by then the value of i will be updated by the outside loop

Arun P Johny
  • 384,651
  • 66
  • 527
  • 531
0

Another way.

var out = [];
for(var i=0; i<3; ++i){
    out.push(i+1);
    setTimeout(function(){
        say("HELLO NUMBER " + out.shift());
    }, i * 2000);
}

function say(text){
    alert(text);
}
HenryYP
  • 76
  • 1
  • 7
0

you need a closure for the value of i for each iteration:

for (var i=1; i<3; i++) {
    (function(j){
        setTimeout(function() { alert("HELLO NUMBER " + j); }, j*2000);
    })(i)
}
Francisco Meza
  • 875
  • 6
  • 8
0
<script>
    function doSetTimeout(i) {
         setTimeout(function() { say("HELLO NUMBER " + i); }, 3000);
    }

    for(var i=1; i<3; i++){
        doSetTimeout(i);
    }

    function say(text){
    alert(text);
   }
</script>
Kousik
  • 21,485
  • 7
  • 36
  • 59