Friday, 6 May 2016

Javascript closure "stores" value at the wrong time



I'm trying to have a counter increase gradually. The following works:



function _award(points){    
var step = 1;
while(points){
var diff = Math.ceil(points / 10);
setTimeout( "_change_score_by("+diff+");" /* sigh */,

step * 25);
points -= diff;
step++;
}
}


However, it uses an implicit eval. Evil! Let's use a closure instead, right?



function _award(points){    

var step = 1;
while(points){
var diff = Math.ceil(points / 10);
setTimeout( function(){ _change_score_by(diff); },
step * 25);
points -= diff;
step++;
}
}



Obviously, this doesn't work. All closures created catch the last value diff has had in the function -- 1. Hence, all anonymous functions will increase the counter by 1 and, for example, _award(100) will increase the score by 28 instead.



How can I do this properly?


Answer



This is a known problem. But you can easily create a closure on each loop iteration:



(function(current_diff) {
setTimeout(function() {_change_score_by(current_diff);},
step * 25);

})(diff);

No comments:

Post a Comment

c++ - Does curly brackets matter for empty constructor?

Those brackets declare an empty, inline constructor. In that case, with them, the constructor does exist, it merely does nothing more than t...