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?
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);
Solving the Closure Loop Problem gets less messy with ECMAScript Fifth Edition's Function#bind
method:
setTimeout(_change_score_by.bind(window, diff), step*25);
You can hack this feature into browsers that don't support it yet to get the benefit now.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With