Search code examples
javascriptsingle-threaded

How does single threading block DOM manipulation in JavaScript?


I hope my title is correct. I was at an interview today and was stumped by a question dealing with the event loop/ single threading. Here is the code:

function longCB(){
    for (var i = 0; i <= 9999; i++){
    console.log(i);
  }
  $('#status').text('hello')
}

$('#status').text('hi')
longCB();

The question was why does the DOM never display 'hi' on the #status div? Being completely stumped the interviewer explained it was because of single threading in javascript and explained that just by adding a setTimeout to longCB() even if it was set to 0 would make it work. After reviewing the event loop/ event que and call stacks I am still completely stumped why this doesn't work? Shouldn't the line

$('#status').text('hi')

be done before even calling longCB()? What am I missing? Thank you in advanced.


Solution

  • That's because the single thread is also shared by the browser's rendering engine. As long as JS is running synchronously, the page on the screen doesn't get updated. Why? Well, say you had this code:

    elem.style.color = 'red';
    elem.style.opacity = '1';
    elem.textContent = 'Hello';
    

    You wouldn't want the element to show the old text in red, then make it more opaque and then change the text to Hello. You just want the text to immediately change and be red and opaque. This is one reason why the rendering is done only after all JS is run. The other reason has to do with performance. Rendering takes time!

    $('#status').text('hi')
    longCB();
    

    You are not wrong when you say that the text is set to 'hi' before even calling longCB(), but since the thread is still running JS, the page won't get redrawn just yet. Using setTimeout simply adds the method call on a stack of things to do at some point in the future, and the browser is guaranteed to render between the end of a synchronous script and handling events or timeouts.