The var
, let
, const
in modern Javascript can be confusing and can cause many logical errors in async environment.
Changing all var
to let
often resolves the issue.
Here is one quick example.
Suppose we have a function that wait a random time and execute another function, passed as argument. The argument function can be handy with closure. We can wrap the context variables into it when building the closure.
Following is the first failed test:
(()=>{
console.log('start');
async function waitAndDo(func){
var wrapper = function(){
func();
}
var timeout = 10000 * Math.random();
setTimeout(wrapper, timeout);
}
var numbers = [1, 2, 3];
for (var i = 0 ; i < numbers.length; i ++) {
var number = numbers[i];
waitAndDo(function(){
console.log('Output number:');
console.log(number);
})
}
})();
The output is:
start
Output number:
3
Output number:
3
Output number:
3
Note that all three numbers used in output are the 3rd one, aka the last execution of the loop.
The fix is simple:
- var number = numbers[i];
+ let number = numbers[i];
Following is the new result:
start
Output number:
2
Output number:
3
Output number:
1