0

I am having trouble understanding why the answer is 9. From my understanding adding the setTimeout function into a for loop means that the setTimeout function will run 3 times for each loop. So it loops 3 times and in each loop, setTimeout runs 3 times for a total of 9 times? I am missing the understanding.

var result = 0;
for (var i = 0; i < 3; i++) {
  setTimeout(function() {
    result += i;
  }, 1000);
}

console.log(result) // answer is 9
mplungjan
  • 169,008
  • 28
  • 173
  • 236
coder87
  • 21
  • 2
  • I get `0` in the snippet I made you because setTimeout returns immediately. You might want to use a closure – mplungjan Mar 22 '21 at 07:06
  • setTimeout() is a async function and you want result at different times. Value will change on time to time. – Erenn Mar 22 '21 at 07:07
  • Because of [Javascript infamous Loop issue?](https://stackoverflow.com/q/1451009) - `i` is always going to be `3` when the callback executes, so `3 + 3 + 3 = 9` – VLAZ Mar 22 '21 at 07:07
  • You need to study and understand async and sync functions. – Erenn Mar 22 '21 at 07:07

1 Answers1

0

Javascript is a single-thread system. setTimeout basically puts your request on the call stack to be executed after 1 second. It is still fired in the scope of your function, but at the end of it, with a 1 second delay. At the end of your function, i === 3 and because you execute it 3 times, you'll get result === 9

You can see this more clearly if you do this:

var result = 0;
for (var i = 0; i < 3; i++) {
  setTimeout(function() {
    result += i;
    console.log("i: " + i);
    console.log("result: " + result)
  }, 1000);
}

You can wrap up your timeout, to break the dependency on i. Do this by placing setTimeout in a function and pass i into it. that way, it doesn't matter what i is, as we are using j which is scoped inside the new function.

var result = 0;
for (var i = 0; i < 3; i++) {
  (function(j){ 
    setTimeout(function() {
      result += j;
      console.log("i: " + i);
      console.log("j: " + j);
      console.log("result: " + result)
    }, 1000);
  })(i);
}
Kevin Verstraete
  • 1,363
  • 2
  • 13
  • 13