Asynchronicity in JavaScript
Explore JavaScript's asynchronous programming by understanding how callbacks work with the event loop and callback queue. Learn to handle non-blocking code flow using functions like setTimeout, and grasp how JavaScript environments manage asynchronous events for efficient execution.
We'll cover the following...
Background
JavaScript supports asynchronous programming. However, writing asynchronous programs is tricky if you don’t have knowledge of the blocking code and JavaScript. Let’s dive deeper into how asynchronicity is engineered in the language.
Callback functions
To leverage asynchronous functions in JavaScript, design callback functions. Callback functions are invoked as soon as the blocking function finishes. Let’s revisit an example.
Above, the complete function acts as the callback function for setTimeout function. When setTimeout function ends, it invokes the callback function and complete is passed to it as an argument. In JavaScript, the setTimeout function is an event. When the event ends, we want to call the callback function of an event. In our case, it is complete function.
Event loop
JavaScript always runs within some environment, from a web browser or to a smart light bulb. These environments use JSEngines to run JavaScript like how Chrome uses the V8 engine. All environments and engines provide JavaScript an event loop. JavaScript hands blocking code or processor independent code (events) to the environment, which schedules and invokes the events. After an event ends, the environment adds the callback function of the event to the callback queue.
The event loop monitors the call stack and callback queue; it moves callback functions into the call stack. Let’s revisit a traditional call stack below.
With the introduction of the event loop and callback queue, our diagram would look like this.
Now, take the previous example but add slight alterations.
We modified our complete function to return a function that on invocation prints the string 'function complete: '. The name variable is passed as an argument to complete. Examine the order of functions. Due to asynchronicity, line 10 is invoked before the two setTimeout functions’ callback functions, followed by the callback function of second setTimeout function of two seconds (line 8), and finally the callback function of the first setTimeout function of five seconds (line 6). The second setTimeout function’s callback function is invoked before, as it ends before one of five seconds.
The event loop monitors the call stack and callback queue. The callback queue is populated via the environment (the web browser) with callback functions of ended events. The event loop:
-
Checks if the call stack is empty.
-
Checks if there are functions in the callback queue.
-
Moves a function from the callback queue to the call stack only when the call stack is empty.
Having an empty call stack doesn’t mean the program ends. The program ends only when all events are ended with an empty call stack and empty callback queue.