0

I have the following code:

function sayHiLater(){
    var greeting = "Hi!";
    setTimeout(function() {
        console.log(greeting);

    }, 3000); 
    console.log("Hello before hi");
}

sayHiLater();

I would like to better understand how event listeners work under the hood, so in my example above, as setTimeOut is being executed, what really happens? I know it creates a new execution context, but my question is; does that execution context is simply being delayed for 3 seconds, meaning the execution stack is moving on to other things in the meanwhile, and as the 3 seconds are over it comes back to that execution context, or is it simply passing to the browser engine some sort of a reference of the anonymous function argument, telling it when to fire, and then right away the setTimeOut execution context is being popped off the execution stack. Or am I just completely far off from what's really happening. Thank you for your time.

RunningFromShia
  • 590
  • 6
  • 20
  • 1
    simple implementation may be: post event into the event queue -> make an executor pull the first event from the event queue-> make the executor look for the evnet callback (from let's say, a map) -> execute the event callback – David Haim Nov 05 '15 at 12:35
  • I removed my answer because I saw this question a possible duplicate of: http://stackoverflow.com/questions/12930272/javascript-closures-vs-anonymous-functions – ambodi Nov 06 '15 at 12:46

1 Answers1

0

Is it simply passing to the browser engine some sort of a reference of the anonymous function argument, telling it when to fire, and then right away the setTimeOut execution context is being popped off the execution stack.

Yes, that's exactly what is happening. The setTimeout execution context immediately returns (and jumps to the next statement, your console.log).

Then after your current turn completes and no more code is to execute, the engine goes back to the event loop and waits for something to happen. After 3 seconds, the time is ready to fire the callback, and when no other code is already executing the event loop starts the anonymous function.
So setTimeout does not really call its callback, it only schedules it for later. It will be called by the event loop itself when the timer has run out.

Notice that the anonymous function that is put on the timer is a closure (it closes over the greeting variable), so the variable environment ("scope") of sayHiLater will be retained (not garbage-collected) even after the sayHiLater execution context is popped off the stack, until the callback is going to be executed.

Community
  • 1
  • 1
Bergi
  • 630,263
  • 148
  • 957
  • 1,375
  • Hey, well the guy above you said that the execution context isn't over, but the execution stack simply moves on to the next thing until the 3 seconds passed, and then it comes back to it(if nothing else is on the stack) and executes that anon function – RunningFromShia Nov 05 '15 at 17:41
  • I was referring to @ambodi comment's. – RunningFromShia Nov 05 '15 at 17:50
  • @user2081462: He might not known what he's talking about :-) Which execution context do you mean, the global one, `sayHiLater()`s one, `setTimeout(…)`s one or the anon callback's one? – Bergi Nov 05 '15 at 17:53
  • I was talking about setTimeout execution context - once you pass arguments to it and execute it, a new execution context happens. My question was - will javascript simply start the execution context, see that there's 3 seconds delay, move on to other things, and then return to the execution context of setTimeout once 3 seconds have passed? or is it the other thing. and btw I am curious to know if it's true to all event listeners. – RunningFromShia Nov 05 '15 at 17:57
  • An execution context is the "stack frame". It only exists during the call. Due to JS' single-threaded nature, and its synchronous run-to-completion (per eventloop turn) model, they typically don't exist very long. Not sure what "*isn't over*" is supposed to mean – Bergi Nov 05 '15 at 17:57
  • I just wrote another comment to clarify, see above – RunningFromShia Nov 05 '15 at 18:00
  • You pass arguments to the call of `setTimeout`, which creates an execution context for the `setTimeout` call (which is implementation-specific, as `setTimeout` is a native host function). It creates a timer and schedules the callback argument, and immediately returns, and with that return the execution context is destroyed. Then when 3 seconds have passed and the event loop picks up the timer, the event loop calls the anon callback. Only then the execution context for the callback will be created. – Bergi Nov 05 '15 at 18:00
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/94357/discussion-between-user2081462-and-bergi). – RunningFromShia Nov 05 '15 at 18:01