Help get this topic noticed by sharing it on Twitter, Facebook, or email.

JavaScript with Promises p.7 ~ 8: What makes the "event loop" turn?

JavaScript with Promises. p. 7 ~ 8 Two examples are provided in which "the event loop turns"; `console.log('Ready when you are')` and either before or upon `xhr.addEventListener`. In the first example, it is not clear what characteristics of a `console.log()` call trigger the event loop to turn. What if there were n number of `console.log()` calls, how many would execute before the marco callback executes or would it be a race condition? In the latter example, it is not clear what triggers the event loop to turn only that it is after the event listeners are added.
2 people have
this question
+1
Reply
  • Hi,

    I passed your message on to the author and he responded with the following message:
    ------
    There is nothing special about calls to console.log in relation to the event loop (as compared to other lines of code). They are used in the examples to show the order in which the code is executing.

    The event loop turns when the JavaScript runtime does not have any more code to immediately execute. More precisely, it is when the JavaScript function at the top of the call stack for the current turn of the event loop returns, as depicted in Figure 1-2 on page 8.

    There is always exactly one function that serves as a starting point for executing your code during a given turn of the event loop. For instance, if you registered a function to handle click events that would be the starting point any time a click event was pulled off the top of the queue.

    function onClick(event) {
    // Each line of code is executed sequentially.
    var a = 1;
    doSomething();
    doMoreStuff();
    a = a + 1;

    // There's no more code now so the onClick function will return.
    // Since it was the starting point for this turn of the event loop
    // control will be returned to the host environment which will
    // allow the loop to turn and other code to be executed.
    }

    Some of the code in the book examples is not contained inside a function. That code is immediately execute when placed in a script. Imagine the code is implicitly wrapped in a function which is called during the first turn of the event loop.

    A script with some code outside a function:

    This is what the script above looks like to the JavaScript runtime:

    Going back to your question, calls to console.log() or any other function prevent the next line of code from being executed until they return which by extension blocks the top most function in the call stack from returning until they are done.

    If there are 500 calls to console.log() or any other functions in the execution path they must all return before the top function in the call stack can return.

    In Examples 1-11 the first iteration of the the loop ends after the call to xhr.addEventListener('error', ...) and in 1-12 the loop ends after the call to setTimeout. In both examples the listener function is invoked in some future turn of the loop after the xhr request completes.

    However, in Example 1-12 the code inside the delayed function does not immediately execute. The call to setTimeout places the delayed function in the queue to be invoked during a future turn of the loop. That creates a race condition because the listener may not be added to the xhr object before the request completes. If the timeout is set to 0 the listener may be added before the request completes. When the timeout is set to a large delay the request is likely to complete before the listener is added. The only sure way to eliminate the race condition is to add the listener in the same turn of the loop as the call to xhr.send() as is done in 1-11.
  • (some HTML allowed)
    How does this make you feel?
    Add Image
    I'm

    e.g. happy, confident, thankful, excited kidding, amused, unsure, silly indifferent, undecided, unconcerned sad, anxious, confused, frustrated