0

In the canonical example* to learn closures, we are presented with the following:

Let’s say we would like to display numbers 1 to 5 at once sequentially. We can accomplish this easily with a simple for loop:

for (var i = 1; i <= 5; i++) {
    console.log(i);    // outputs 1 2 3 4 5
}

The code block above should output 1 2 3 4 5 in the console. But what if we want to delay the output and have each number display 1 second apart from each other consecutively? The setTimeout() function seems like the perfect candidate for the job:

for (var i = 1; i <= 5; i++) {
  setTimeout(function() { console.log(i); }, 1000*i); //outputs 6 6 6 6 6
}

The above code seems like the obvious answer. We put console.log(i) within an anonymous function inside a setTimeout() function, and set each setTimeout() to be delayed 1 to 5 seconds (1000 x 1, 1000 x 2…) respectively. However, as soon as we run that codes, we know something is wrong. The numbers are each outputting to console 1 second after another consecutively, but they are all 6s. So we now have 6 6 6 6 6 as the end result.

From my understanding of loops...

We set the iterator, in our case: var i = whatever number you'd like;

We set the condition: i <= 5;

We set the incrimentor: i++

We then we wrap what we want to execute in a set of {} in our case:

   { 
     setTimeout(function() { 
       console.log(i); 
     }, 1000 * i);
   }

But I thought the sequence which followed was:

  1. Condition gets evaluated to see if block will fire
  2. Code block gets executed
  3. Incriminator fires
  4. Variable is assigned to the new value (from the incriminator)
  5. Goes back to check condition will fire or loop will end

* I referenced this blog for the loop and insights....

Antonio Pavicevac-Ortiz
  • 7,239
  • 17
  • 68
  • 141
  • because it reads the value of `i` when it runs – epascarello Jun 08 '17 at 16:47
  • @epascarello Doesn't the console log do as well? – Antonio Pavicevac-Ortiz Jun 08 '17 at 16:48
  • when you are in a timeout, the loop has finished so it is at the last value, the inside of the timeout is still referencing i, so when it runs it reads the current value, not what it was when you set the function. – epascarello Jun 08 '17 at 16:49
  • https://stackoverflow.com/questions/750486/javascript-closure-inside-loops-simple-practical-example – epascarello Jun 08 '17 at 16:50
  • @epascarello Thanks for the reference! But I think you hit what my point is right on the head. Why does setTimeout wait till the loop is completely done? It can't be because of the time passed as the second argument, `1000 * i` because if you omit it, it stills spits back `5` 4x's, but just omitting the delay.... – Antonio Pavicevac-Ortiz Jun 08 '17 at 17:01
  • because the loop executes and does not wait for the asynchronous timeouts.. It is not start loop, set timeout, wait until timeout runs, than next iteration. It is start, set timeout, next iteration, set timeout .... – epascarello Jun 08 '17 at 17:12
  • So do you mean a loop will ignore anything which would be asynchronous? – Antonio Pavicevac-Ortiz Jun 08 '17 at 17:18
  • It is like you call 3 different delivery places one for pizza, one for Chinese, and one for ice cream. You are not going to wait for each one to deliver the food so you make the next call. You call each one in order and eventually they show up at your house. that is how asynchronous processes work. – epascarello Jun 08 '17 at 17:21
  • Thanks for the illustration.... – Antonio Pavicevac-Ortiz Jun 08 '17 at 17:25

0 Answers0