0

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

What I want to ask is that since the output is 6, the time interval should also be 6,but tht time interval is 1*1000. This is 《you don't know js》page 46。 I understand why the output is 6, but I don't understand why the interval is not 6

webdisplay
  • 25
  • 5
  • 2
    replace `var` with `let`... – decpk Jun 22 '21 at 07:40
  • 1
    Because `var` declarations are function/global scoped. There is only one `i` variable and every function refers to the same variable. – Felix Kling Jun 22 '21 at 07:40
  • 1
    @Yousaf: No, it works fine as it is. `i*1000` is executed in each iteration of the loop. – Felix Kling Jun 22 '21 at 07:42
  • What I want to ask is that since the output is 6, the time interval should also be 6 – webdisplay Jun 22 '21 at 07:45
  • @webdisplay, you initialize ```i = 1``` but not ```i = 0```, the last increment make it 6 and that's why 5 setTimeout only. – ikhvjs Jun 22 '21 at 07:46
  • @FelixKling right; i mis-read the code, thinking OP wanted to avoid the closures inside the loop and `i * 1000` was supposed to be passed to the IIFE – Yousaf Jun 22 '21 at 07:47
  • You are creating 5 timeouts, with 1000ms, 2000ms, 3000ms, 4000ms and 5000ms delay. You do this with a loop that increments `i`. Then the `for` loop terminates because eventually `i == 6` which means `i <= 5` is `false`. Then the timeout scheduled after 1000ms is called and logs the value of `i`, which is `6`. – Felix Kling Jun 22 '21 at 07:50
  • *"but I don't understand why the interval is not 6"* `i * 1000` is evaluated in every iteration. In the first iteration `i` has the value `1`: `1 * 1000 = 1000`. In the second iteration `i` has the value `2`: `2 * 1000 = 2000`, ... in the last iteration, `i` has the value `5`: `5 * 1000 = 5000`. – Felix Kling Jun 22 '21 at 07:52
  • Felix Kling wrote: _"Because `var` declarations are function/global scoped. There is only one `i` variable and every function refers to the same variable."_ When the inline function is called the value of `i` is `6`. But the function is called 5 times, for the values 1, 2, 3, 4, 5. At the end `i` has the value `6` but `i <= 5` returns `false` and the function isn't called. –  Jun 22 '21 at 08:08
  • 1
    *"I suggest you run this code, although it looks very simple, but the result is output 6 times every 1 second, a total of 5 times. I expect to output a 6 every 6 seconds, a total of 5 times"* I don't know what else to say. I already explained that the expression `i * 1000` is executed *in each iteration of the loop* and in each iteration `i` has a different value. That means the first `setTimeout` is scheduled `1000ms` in the future, the second `2000ms`, etc. Yes, that results in a new `console.log` message every second. – Felix Kling Jun 22 '21 at 08:09
  • If you add `console.log(i * 1000)` before the call to `setTimeout` you will see the value. If you want each of those timeouts to be 6 seconds apart you would have to use `i * 6000` instead. – Felix Kling Jun 22 '21 at 08:10
  • 1
    The `setTimeout` is called 5 times almost immediately with timeouts 1000, 2000, 3000, 4000, 5000. The first output is logged after 1 second (from start, after `setTimeout` was called). The second output is logged 2 seconds (from start, after `setTimeout` was called, not after first output). The third output is logged 3 seconds (from start, after `setTimeout` was called)... –  Jun 22 '21 at 08:10
  • 1
    It executes every second because the difference between the timeouts is one second. 2000 (second output) - 1000 (first output) === 1000. 3000 (third output) - 2000 (second output) === 1000. 4000 (fourth output) - 3000 (third output) === 1000. The first output is logged after 1 second. The second output is logged after 2 seconds, one second after the first output... Maybe you'll understand if you change the timeout to a fixed `1000`. All 5 outputs will be logged almost at the same time. The for loop doesn't wait for the callback function to return. –  Jun 22 '21 at 08:13
  • 2
    @jabaa I get it. Thanks everyone! – webdisplay Jun 22 '21 at 08:19
  • You can't choose an answer. This question was closed as a duplicate. These are comments. No answer was given. –  Jun 22 '21 at 08:36

0 Answers0