How do global variables impact async functions? Does hoisting have a role to play at all?
As many beginners have found out the hard way - yes.
for (var i = 0; i < 5; i++) {
setTimeout(function() {
console.log(i);
}, 500 * i);
}
What’s the output you’d expect?
// 0 1 2 3 4
What you get -
// 5 5 5 5 5
If you have not already figured it out, the behaviour is because of the var used in for loop.
The process flow is -
- start program
- start executing
forloop and initiate 5 different async routines - most likely the program will end. So,
i(within async routine) is set to 5 by this time - first async routine starts, gets
ifrom global scope, and prints out thei(=5) iin the outer loop (500 * i) will be set and reset to 0, 1, 2, etc. as expected.- all other async routines follow the same ‘routine’
You can make one small change and make a huge difference.
for (let i = 0; i < 5; i++) {
setTimeout(function() {
console.log(i);
}, 500 * i);
}
// 0 1 2 3 4
The above code will run like so -
- start program
- start executing
forloop and initiate 5 different async routines - most likely the program will end. So,
iis set to 5 by this time - first async routine starts, refers to
icopy from theforwhich initiated it (=0). This is similar to Javascript remembering the values at the time of function call in case of closures - second async routine starts, refers to
icopy from theforagain (=1) and the cycle continues iin the outer loop (500 * i) will be set and reset to 0, 1, 2, etc. as expected.- all other async routines follow the same ‘routine’