Skip to content

How asynchronous JavaScript works under the hood

Daisho Komiyama edited this page Jul 25, 2019 · 12 revisions

Hi, Today, I watched an amazing tutorial video about JavaScript asynchronous features and learned how it works under the hood.

Exercise 1

What is the order of 3 function executions?

function printHello () {
    console.log('Hello');
}

function blockFor1Sec () {
    //assume looping on huge array and it takes approximately 1 second to complete
}

setTimeout(printHello, 0);

blockFor1Sec();

console.log('Me first!');

What happens under the hood

async analogy

Answer

  • blockFor1Sec (1ms - 1001ms)
  • 'Me first!' (1002ms) from console.log
  • 'Hello' (1003ms) from printHello

Explanation

When setTimout (Web browser feature) is used, the function in callback parameter position, in this case printHello, is pushed to Callback Queue and it won't be pushed to Call Stack until all global functions executed. So in this case, blockFor1Sec() and console.log('Me first!') are executed before printHello even setTimeout's timer was expired long ago.

Exercise 2

What is the order of those functions executions?

function display (data) {
    console.log(data);
}

function printHello () {
    console.log('Hello');
}

function blockFor300ms () {
    //blocks js thread for 300ms with long lasting loop
}

setTimeout(printHello, 0);

const futureData = fetch('https://twitter.com/kdaisho/tweets/1'); //'Hi'
futureData.then(display);

blockFor300ms();

console.log('Me first!');

What happens under the hood

async with xhr analogy

Answer

  • blockFor300ms (3ms - 303ms)
  • 'Me first!' (303ms) from console.log
  • 'Hi' (304ms) from display
  • 'Hello' (305ms) from printHello

Explanation

Like you've seen with exercise 1, setTimeout is pushed to Callback Queue after 1ms and it waits there until all global functions executed. But here's another "facade function" this time; it's fetch. fetch is another web browser feature which uses XMLHttpRequest (xhr). fetch's job could be done after 200ms for this scenario but like setTimout, it's not allowed to be pushed into Call Stack right away even its job is done. Instead its function at onFulfillment position is pushed to Micro Task Queue which JavaScript spec itself calls Job Queue. Difference between setTimout and fetch is fetch has an impact on JavaScript execution thread by returning an object, but setTimeout does not. Event loop is responsible checking if Call Stack is emptied out and pushing any functions in the queue when it's clear. It prioritizes Micro Task Queue over Callback Queue. So display function in Micro Task Queue gets pushed to Call Stack first then after it finishes Event loop pushes printHello function from Callback Queue to Call Stack then it gets executed.

Clone this wiki locally