3

Possible Duplicate:
Javascript closure inside loops - simple practical example
Calling setTimeout function within a loop

before calling this a duplicate, I looked on the internet and everyone seemed to have different problems. If anybody could help me with this particular one, it'd be greatly appreciated.

Basicaly, what I have is two for loops nested inside a 3rd one.

for (a=0 ... a++) {
    for (b=0 ... b++) {
        setTimeout( ... + a + ..., 1000*b);
    }
    for (c=0 ... c++) {
        setTimeout( ... + a + ..., 1000*c);
    }
}

This is some pseudo code just to avoid the junk, but basically I want to pass the a value to the callback function triggered by the timer. The problem comes from the fact a is being incremented, so when then event is fired, the function has the last value of a instead of the one one it one registered.

I can think of it like a reference or a pointer in C/C++, this is really annoying. Any way to give it a permanent value?

Community
  • 1
  • 1
  • 2
    [Here is a very similar question.](http://stackoverflow.com/questions/5986588/calling-settimeout-function-within-a-loop) – Pointy Jul 23 '12 at 18:47
  • The reason it is a duplicate is because the problem you are having is an exact duplicate of hundreds of other similar questions. The code involved may be different, but the problem and solution are the same. – Kevin B Jul 23 '12 at 18:57
  • @KevinB: It's hard to look for a concept or a paradigm on internet when you don't even know its existence or the name. Thank you for your immensely constructive comment but this question is already been solved. –  Jul 23 '12 at 18:59
  • Also be sure to declare your variables with `var` (maybe you are, but not in the posted code, so just in case) – Pointy Jul 23 '12 at 19:02
  • @Pointy: I did. It's a bit messy but here you go: https://gist.github.com/3164343 –  Jul 23 '12 at 19:37

1 Answers1

4

A closure in it's simplest form would do the trick:

for (a=0 ... a++) {
    (function(a){
       for (b=0 ... b++) {
           setTimeout( ... + a + ..., 1000*b);
       }
       for (c=0 ... c++) {
           setTimeout( ... + a + ..., 1000*c);
       }
    })(a);
}

To take Pointys answer into account: One should never pass a string to setTimeout.

You can use the 3-parameters form of setTimeout and pass a function (or a reference to a function), the time value and the parameters for the function:

for (a=0 ... a++) {
     for (b=0 ... b++) {
         setTimeout( function(x){ /*do stuff, using x */}, 1000*b, a);
     }
}

Note however, that unfortunately the 3 parameter form does not work in Internet Explorer.

Christoph
  • 50,121
  • 21
  • 99
  • 128
  • 2
    Actually I don't think this constitutes very good advice. You really should not be passing strings to `setTimeout()`. – Pointy Jul 23 '12 at 18:50
  • @Pointy Actually, you don't know if the OP is doing this, since this is only pseudocode. But i agree if it was. However thats not part of the question. No reason for DV imo. – Christoph Jul 23 '12 at 18:51
  • @Pointy: Don't worry, it's an annonymous function. The closure is my solution. Just waiting the 10 min to accept his answer. –  Jul 23 '12 at 18:51
  • Finally a simple and clear example ! (the first) – realtebo Mar 23 '13 at 18:04