This page looks best with JavaScript enabled

Global variables in async functions

 ·   ·  ☕ 2 min read

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.

1
2
3
4
5
for (var i = 0; i < 5; i++) {
  setTimeout(function() {
    console.log(i);
  }, 500 * i);
}

What’s the output you’d expect?

1
// 0 1 2 3 4

What you get -

1
// 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 for loop 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 i from global scope, and prints out the i (= 5)
  • i in 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.

1
2
3
4
5
6
7
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 for loop and initiate 5 different async routines
  • most likely the program will end. So, i is set to 5 by this time
  • first async routine starts, refers to i copy from the for which 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 i copy from the for again (= 1) and the cycle continues
  • i in 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’
Stay in touch!
Share on

Prashanth Krishnamurthy
WRITTEN BY
Prashanth Krishnamurthy
Technologist | Creator of Things