2

Possible Duplicate:
setTimeout in a for-loop and pass i as value

i am trying generate dynamic array and using this array as loop .. but in loop settime out is not working or function is not working. Here is my code

jQuery(document).ready(function () {
    temp = new Array();
    generateArray(temp);

    function generateArray(temp) {
        if (temp.length < 10) {
            res = randomXToY(1, 10, 0);
            for (var k = 0; k < temp.length; k++) {
                if (temp[k] == res) {
                    var test = 1;
                }
            }
            if (test != 1) {
                temp.push(res);
                //abc(temp);
            }
            generateArray(temp);
        } else {
            for (var z = 0; z < 10; z++) {
                tnest(temp[z]);
                setTimeout(function () {
                    removeClassImg(temp[z])
                }, 3000);
            }
            temp = new Array();
            generateArray(temp);
        }
    }

    function removeClassImg(result1) {
        alert(result1);
        $('#img' + result1).fadeTo(12000, 0.1);
        return true;
    }

    function tnest(result) {
        alert(result);
        $('#img' + result).fadeTo(12000, 1);
        return true;
    }

    function randomXToY(minVal, maxVal, floatVal) {
        var randVal = minVal + (Math.random() * (maxVal - minVal));
        return typeof floatVal == 'undefined' ? Math.round(randVal) : randVal.toFixed(floatVal);
    }
});

alert in function removeClassImg is not working .. i am using settimeout in for loop this is not working fine.

Community
  • 1
  • 1
harpreet kaur
  • 143
  • 1
  • 3
  • 10

2 Answers2

4

It has something to do with the timeout and loops. you need to wrap it in a closure so that your timeout callback is bound to the value of z "at that time".

I also notice this after the loop:

temp = new Array();
generateArray(temp);

by the time you wanted to operate your delayed operation, your array does not contain the values you need anymore. You already cleared them.

try this:

for (var z = 0; z < 10; z++) {
    (function (tz) {                  //"localize" temp[z] by creating a scope
        tnest(tz);                    //that makes temp[z] local. this is done
        setTimeout(function () {      //by creating an immediate function
            removeClassImg(tz)        //passing temp[z] into it. that way, the 
        }, 3000);                     //timeout receives a local temp[z] which
    }(temp[z]));                      //has the value of temp[z] "at that time"
}

Here's a sample with the closure and a sample without it. After 3 seconds, you will see that the one without it will log all 10s instead of 0-10.

Joseph
  • 117,725
  • 30
  • 181
  • 234
2

That's because you're accessing to variable z in the function you set in the setTimeout, creating a closure, and z is used in the loop. It means, you will probably end up to have z equals to 10 when the setTimeout invokes the function.

I already discussed about this issue and possible solutions here: How to pass a variable into a setTimeout function? I think it will help you!

Community
  • 1
  • 1
ZER0
  • 24,846
  • 5
  • 51
  • 54