Article

Registering callbacks in the Event Table

This is in continuation to JavaScript runtime: Call Stack and Event Queue - Part 2

Registering callbacks in Event Table

When the following code is executed,

btn.addEventListener('click', function() {
    console.log("Btn Clicked!");
});
inp.addEventListener('keydown', function() {
    alert("Key Pressed!");
});

the browser registers the two event handlers associated with the 'click' and 'keydown' events respectively in the event table. When an event occurs, for example, the user presses a key in the input box, the browser looks up the event table if there is any associated callback registered for that event. If it finds one, it pushes the callback function (alert in our example) to the queue where it waits for its turn to get executed.

An event queue is a staging area that enqueues messages and associated callbacks waiting to be processed and the event loop continually monitors the queue for messages. When the call stack is empty, the first callback in the queue is moved to the call stack for execution, and so on.

Monitoring the queue for callbacks in a loop

You can imagine the event queue as simply a stopping place en route to a destination. JavaScript runtime has an event queue which is a (temporary stopping place) which is used to store a list of callback functions that are waiting to be invoked and moved over to the call stack (destination) and then processed there. On the other hand, note that the synchronous function calls are directly added as new stack frames onto the call stack.

The event queue is implemented as a FIFO data structure, meaning that callbacks execute in the order they are added onto the queue. Note that the functions held in the event queue won't get executed until all of the functions in the call stack are executed no matter how time consuming they are. Let us discuss this in a little detail.

The JavaScript runtime has a process that constantly checks whether there are any stack frames in the call stack. If there are any, the runtime processes those frames and executes the functions associated with those frames. Whenever the call stack is empty, the event loop then pays attention to the event queue and checks to see if it has any functions waiting to be invoked. If there are one or more functions stored in the queue, then the runtime removes the first function from the queue, pushes it into the call stack, and executes it, and so on. Even if the event queue is empty, the monitoring process just keeps on running indefinitely, and therefore, this it is called the event loop.

Note that when a function is grabbed off of the queue and placed in the call stack, that function is executed/processed completely until it reaches its synchronous completion. In this way, you can safely assume that a function will always execute to completion, without interruption, before any other code is executed.

The event messages are placed in the event queue in response to events, such as timeout, mouse being clicked, etc. given a callback function has been provided. When an event is fired, the associated callback is called with the event as a parameter. But if an event occurs and no associated callback function is provided, no message will be placed in the queue.

For Part 4, click this link: JavaScript runtime: Call Stack and Event Queue - Part 4