So it seems that i is passed by reference instead of value. How do I pass i by value?
actually, numbers ARE passed by value, but you're not passing anything...
when it fires, the timedout function looks to the only i it knows: the loop counter. by this time, the loop counter is set at the last position, so they are all 2.
to remedy this unpleasant situation, i moved to Array.map and don't use loops anymore.
but you can also take advantage of the fact that numbers are passed by value, and pass the value of i to a fresh i that your timeout function will see instead of the loop counter, simply by using another function to create private scope inside the loop:
Code:
var ret = new Array();
for (var i = 0; i < 3; i++) {
(function(i){
window.setTimeout(
function(){ ret.push(i); },
1000
);
}(i));
}
window.setTimeout(function() {
document.write("ret[0]="+ret[0]+" (expected 0)<br/>\n");
document.write("ret[1]="+ret[1]+" (expected 1)<br/>\n");
document.write("ret[2]="+ret[2]+" (expected 2)<br/>\n");
},1500);
mrhoo: thanks, I actually didn't know about setInterval until now , thanks for the tip. I'll start using it another part of my code. However in my case the code inside the for-loop needs to be run in sequence for the three i's. The code contains a callback-section which needs to complete before the next iteration is started so I need to use setTimeout instead of setInterval to better control the timing and "interaction between the threads (in a way)".
Until now I've been using a global variable to count each time the function is called but passing the i as a value would be more elegant.
mrhoo: after a second look I see that your code of course also runs in sequence and would usually work in my case too. However if the callback-section in my code (not included in the example code) is not called and completed within 1000ms, then the next iteration would start and my script would fail. Would work for the example though.
Bookmarks