Nonblocking JavaScript
First of all, let's look at what really happens when we do things asynchronously. Whenever we invoke a function in JavaScript, it creates a new stack frame (execution object). Every inner call gets into this frame. Here the frames are pushed and popped from the top of the call stack in the
LIFO (last in, first out) manner. In other words, in the code, we call the foo
function and then the bar
function; however, during execution, foo
calls the baz
function. In this case, in the call
stack, we have the following sequence: foo
, baz
, and only then bar
. So bar
is called after the stack frame of foo
is empty. If any of the functions perform a CPU-intensive task, all the successive calls wait for it to finish. However, JavaScript engines have
Event Queues (or task queues).
If we subscribe a function to a DOM event or pass a callback to a timer (setTimeout
or setInterval
) or through any Web I/O APIs (XHR, IndexedDB, and FileSystem), it ends up in a corresponding queue. Then...