Monday, 14 August 2017

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

casting - Why wasn't Tobey Maguire in The Amazing Spider-Man? - Movies & TV

In the Spider-Man franchise, Tobey Maguire is an outstanding performer as a Spider-Man and also reprised his role in the sequels Spider-Man...