-3

Given the following example:

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

This prints out:

1
2
3
4
5
6
6
6
6
6

setTimeout does not get executed immediately but rather after the loop has ended, despite the fact that console.log got executed immediately with each iteration within the loop.

I did a little research into this, but the most information I could find stated that although the anonymous function within setTimeout was added to the task queue that JavaScript executes, it doesn't necessarily get called immediately.

My question is that how does the browser determine which functions get priority in terms of execution?

the12
  • 2,395
  • 5
  • 19
  • 37
  • 4
    `setTimeout` *does* get immediately executed, but the function `timer` you passed to it does not - that's the whole point. – Bergi Oct 10 '17 at 22:04
  • 1
    Have a look at https://developer.mozilla.org/en-US/docs/Web/JavaScript/EventLoop . JavaScript guarantees that the functions passed to the `setTimeout` calls will be called *after* the current execution context terminates. Which is exactly what you are seeing here. – Felix Kling Oct 10 '17 at 22:04
  • I believe the minimum delay for `setTimeout` [is 4 ms](https://stackoverflow.com/q/9647215/5743988). – 4castle Oct 10 '17 at 22:05
  • Remember that JavaScript is singlethreaded, it first completes the loop and after that starts processing the functions in the timeouts. It blocks input. Set a timeout and after that start an infinite loop and see if input from the timeout is getting through (it's not). – Mouser Oct 10 '17 at 22:05
  • Isn't this a duplicate btw? – Mouser Oct 10 '17 at 22:07
  • Well, your question is wrong. It assumes `setTimeout` does not get executed immediately for some reason, but it does. You don't explain why you think `setTimeout` doesn't get executed, so I'm not sure what there is to answer. This question isn't useful. – melpomene Oct 10 '17 at 22:42
  • @melpomene @Bergi Does `setTimeout` get executed immediately though? Thanks to @Eneko, researched it, and apparently if I've understood correctly, `setTimeout` is actually asynchronous code, and gets added to the callback AFTER all the other codes are executed. http://www.hiddenwebgenius.com/blog/guides/understanding-javascripts-asynchronous-code/. Also, if it was executed immediately, wouldn't it have showed up as 1 2 3 4 5 (for setTimeout, if was executed immediately). – the12 Oct 10 '17 at 22:49
  • 1
    @the12 `setTimeout` is executed immediately. Your `timer` function is executed asynchronously because that's what `setTimeout` does: It takes the function you give it and registers it to be run later. – melpomene Oct 10 '17 at 22:52
  • @melpomene Ok.. after looking into it further, apparently it's called a callback, a function as a parameter, and all callbacks in JavaScript are asynchronous. Thanks a lot for your help! – the12 Oct 10 '17 at 23:05
  • @the12 Callbacks aren't necessarily asynchronous. See [`Array.prototype.sort`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/sort) for an example of a synchronous callback (the comparison function). – melpomene Oct 10 '17 at 23:09

1 Answers1

2

The reason you are getting this response is that every time you enter the loop you are setting a new timeout.

Timeouts are put in the stack and executed when the loop is finished. This may confound you because when you use a function inside a function in synchronous code, the parent pauses its execution until the child finishes. But when an asynchronous function is called (just like setTimeout()) the behaviour is quite different.

Check this post: Asynchronous vs synchronous execution, what does it really mean?