Friday, July 26, 2019

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

plot explanation - Why did Peaches' mom hang on the tree? - Movies & TV

In the middle of the movie Ice Age: Continental Drift Peaches' mom asked Peaches to go to sleep. Then, she hung on the tree. This parti...