Asynchronous I o Single Thread Loop Continuation
JavaScript is a single-threaded language and, at the same time, also non-blocking, asynchronous and concurrent. This article will explain to you how it happens.
Runtime
JavaScript is an interpreted language, not a compiled one. This means that it needs an interpreter which converts the JS code to a machine code. There are several types of interpreters (known as engines). The most popular browser engines are V8 (Chrome), Quantum (Firefox) and WebKit (Safari). Incidentally, V8 is also used in a popular non-browser runtime, Node.js.
Each engine contains a memory heap, a call stack, an event loop, a callback queue and a WebAPI with HTTP requests, timers, events, etc., all implemented in its own way for faster and safer interpretation of the JS code.
Basic JS runtime architecture. Author: Alex Zlatkov
Single Thread
A single-thread language is one with a single call stack and a single memory heap. It means that it runs only one thing at a time.
Astack
is a continuous region of memory, allocating local context for each executed function.
Aheap
is a much larger region, storing everything allocated dynamically.
Acall stack
is a data structure which basically records where we are in the program.
Call Stack
Let's write a simple code and track what's happening on the call stack.
As you can see, the functions are added to the stack, executed and later deleted. It's the so-called LIFO way - Last In, First Out. Each entry in the call stack is called astack frame
.
Knowledge of the call stack is useful for reading error stack traces. Generally, the exact reason for the error is at the top in first line, though the order of code execution is bottom-up.
Sometimes you can deal with a popular error, notified byMaximum call stack size exceeded
. It is easy to get this using recursion:
function foo ( ) { foo ( ) } foo ( )
and our browser or terminal freezes. Each browser, even their different versions, has a different call stack size limit. In the vast majority of cases, they are sufficient and the problem should be looked for elsewhere.
Blocked Call Stack
Here is an example of blocking the JS thread. Let's try to read afoo
file and abar
using the Node.js synchronous functionreadFileSync
.
This is a looped GIF. As you see, the JS engine waits until the first call inreadFileSync
is completed. But this will not happen because there is nofoo
file, so the second function will never be called.
Asynchronous Behavior
However, JS can also be non-blocking and behave as if it were multi-threaded. It means that it doesn't wait for the response of an API call, I/O events, etc., and can continue the code execution. It is possible thanks to the JS engines which use (under the hood) real multi-threading languages, like C++ (Chrome) or Rust (Firefox). They provide us with the Web API under the browser hoods or ex. I/O API under Node.js.
In the GIF above, we can see that the first function is pushed to the call stack andHi
is immediately executed in the console.
Then, we call thesetTimeout
function provided by the browser's WebAPI. It goes to the call stack and its asynchronous callbackfoo
function goes to the WebApi's queue, where it waits for the call, set to happen after 3 seconds.
In the meantime, the program continues the code and we seeHi. I am not blocked
in the console.
After it is invoked, each function in the WebAPI queue goes to theCallback Queue
. It is where functions wait until the call stack is empty. When it happens, they are moved there one by one.
So, when oursetTimeout
timer finishes the countdown, ourfoo
function goes to the callback queue, waits until the call stack becomes available, goes there, is executed and we seeHi from asynchronous callback
in the console.
Event Loop
The question is, how does the runtime know that the call stack is empty and how is the event in the callback queue invoked? Meet event loop. It is a part of the JS engine. This process constantly checks if the call stack is empty and, if it is, monitors whether there is an event in the callback queue waiting to be invoked.
That's all the magic behind the scenes!
Wrapping up the Theory
Concurrency & Parallelism
Concurrency
means executing multiple tasks at the same time but not simultaneously. E.g. two tasks works in overlapping time periods.
Parallelism
means performing two or more tasks simultaneously, e.g. performing multiple calculations at the same time.
Threads & Processes
Threads
are a sequence of code execution which can be executed independently of one another.
Process
is an instance of a running program. A program can have multiple processes.
Synchronous & Asynchronous
Insynchronous
programming, tasks are executed one after another. Each task waits for any previous task to be completed and is executed only then.
Inasynchronous
programming, when one task is executed, you can switch to a different task without waiting for the previous one to be completed.
Synchronous and Asynchronous in a Single and Multi-threaded Environment
Synchronous with a single thread
: Tasks are executed one after another. Each task waits for its previous task to get executed.
Synchronous with multiple threads
: Tasks are executed in different threads but wait for any other executing tasks on any other thread.
Asynchronous with a single thread
: Tasks start being executed without waiting for a different task to finish. At a given time, only a single task can be executed.
Asynchronous with multiple threads
: Tasks get executed in different threads without waiting for other tasks to be completed and finish their executions independently.
JavaScript classification
If we consider how JS engines works under the hood, we can classify JS as an asynchronous and single-threaded interpreted language. The word "interpreted" is very important because it means that the language will always be runtime-dependent and never as fast as compiled languages with built-in multi-threading.
It is noteworthy that Node.js can achieve real multi-threading, provided that each thread is started as a separate process. There are libraries for this, but Node.js has a built-in feature called Worker Threads.
All event loop GIFs come from the Loupe application created by Philip Roberts, where you can test your asynchronous scenarios.
Read more:
Why you should (probably) use Typescript?
Quality first! 5 easy steps to lint your code with GitHub workflows in JavaScript project
How to improve Vue.js apps? Some practical tips
Source: https://thecodest.co/blog/asynchronous-and-single-threaded-javascript-meet-the-event-loop
Post a Comment for "Asynchronous I o Single Thread Loop Continuation"