<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Ion RA</title>
    <description>The latest articles on DEV Community by Ion RA (@ionra).</description>
    <link>https://dev.to/ionra</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F920255%2Fae7447cd-2a8e-4a3f-b829-645d0f9cffa0.jpeg</url>
      <title>DEV Community: Ion RA</title>
      <link>https://dev.to/ionra</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/ionra"/>
    <language>en</language>
    <item>
      <title>Overview of Caching in Web Software Development</title>
      <dc:creator>Ion RA</dc:creator>
      <pubDate>Fri, 17 Mar 2023 14:36:32 +0000</pubDate>
      <link>https://dev.to/ionra/overview-of-caching-in-web-software-development-5fo2</link>
      <guid>https://dev.to/ionra/overview-of-caching-in-web-software-development-5fo2</guid>
      <description>&lt;p&gt;This is a brief overview of caching with emphasis on web software development.&lt;/p&gt;




&lt;h2&gt;
  
  
  What is caching?
&lt;/h2&gt;

&lt;p&gt;Caching is the temporary storage of data in designed locations of a computing environment.&lt;/p&gt;

&lt;p&gt;This is typically done to improve responsiveness and reduce roundabout requests to data stores.&lt;/p&gt;

&lt;p&gt;It can also be used to reduce redundant computations, as might be the case with &lt;a href="https://en.wikipedia.org/wiki/Memoization"&gt;&lt;strong&gt;memoization&lt;/strong&gt;&lt;/a&gt;, in which case the cached data might also be the results of computations that are stored for later retrieval.&lt;/p&gt;

&lt;p&gt;The most common cache on the web is the &lt;a href="https://httpwg.org/specs/rfc9111.html"&gt;&lt;strong&gt;HTTP cache&lt;/strong&gt;&lt;/a&gt;, which represents data from responses that is stored in specific locations to be reused and managed according to HTTP cache specifications.&lt;/p&gt;




&lt;h2&gt;
  
  
  Where is the cache phisically stored?
&lt;/h2&gt;

&lt;p&gt;Caches are physically stored in &lt;a href="https://www.techtarget.com/searchstorage/definition/cache-memory"&gt;&lt;strong&gt;cache memory&lt;/strong&gt;&lt;/a&gt;, which are typically chips (e.g. SRAM) that are integrated or interconnected with various processing units (e.g. CPU, GPU, etc.).&lt;/p&gt;




&lt;h2&gt;
  
  
  When is it appropriate to cache?
&lt;/h2&gt;

&lt;p&gt;Expanding on what was said above, one use case is when the data is consistent during the session.&lt;/p&gt;

&lt;p&gt;Another is in some situations when SQL queries are resource heavy.&lt;/p&gt;

&lt;p&gt;It is worth mentioning that caching could be beneficial when the need to save costs is significant and a priority.&lt;/p&gt;




&lt;h2&gt;
  
  
  What are the most important attributes of HTTP caching?
&lt;/h2&gt;

&lt;p&gt;Broadly speaking, there are two major attributes:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://httpwg.org/specs/rfc9111.html#expiration.model"&gt;&lt;strong&gt;Freshness&lt;/strong&gt;&lt;/a&gt; it's a property that sets an expiration frame for the cache and dictates whether or not the cached data is up to date and still relevant for use by the client.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://httpwg.org/specs/rfc9111.html#validation.model"&gt;&lt;strong&gt;Validation&lt;/strong&gt;&lt;/a&gt; dictates the techniques for checking with the origin server the expired cached data in order to renew the expiration date or update the cache.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;




&lt;h2&gt;
  
  
  Are there any common practices regarding HTTP caching?
&lt;/h2&gt;

&lt;p&gt;Be aware of &lt;a href="https://developer.mozilla.org/en-US/docs/Web/HTTP/Caching#heuristic_caching"&gt;&lt;strong&gt;heuristic caching&lt;/strong&gt;&lt;/a&gt;, it basically involves always caching data on certain conditions unless otherwise specified. It is best to explicitly set some default cache settings based on your expectations.&lt;/p&gt;

&lt;p&gt;For cache that needs to be updated more often than the expiration period suggests, it's good to consider &lt;a href="https://developer.mozilla.org/en-US/docs/Web/HTTP/Caching#cache_busting"&gt;&lt;strong&gt;cache busting&lt;/strong&gt;&lt;/a&gt;, this means adding a unique symbol to its file name. That way, if a new update is available and ready, it can be downloaded by the browser because it is seen as a new resource, thus bypassing the original cache before the timeout expires.&lt;/p&gt;

&lt;p&gt;Make it a habitt to check and enforce cache validation.&lt;/p&gt;

&lt;p&gt;Usually don't cache resources that can't be cache busted. Do it unless you need more aggressive caching and have mechanisms in place that explicitly purge the cache when it's time for updates.&lt;/p&gt;




&lt;h2&gt;
  
  
  What are some common classifications of web caching?
&lt;/h2&gt;

&lt;p&gt;Altough there are many carachteristics by which caches can be classified, here are two important ones:&lt;/p&gt;

&lt;p&gt;Classification by accessibility:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://httpwg.org/specs/rfc9111.html#rfc.section.4.2.2:~:text=an%20intermediary.%20A-,private%20cache,-%2C%20in%20contrast%2C%20is"&gt;&lt;strong&gt;Private cache&lt;/strong&gt;&lt;/a&gt;, here all cached data is available only to one client, the browser's cache system usually works as a private cache.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://httpwg.org/specs/rfc9111.html#rfc.section.4.2.2:~:text=A-,shared%20cache,-is%20a%20cache"&gt;&lt;strong&gt;Shared cache&lt;/strong&gt;&lt;/a&gt;, here cached data is available and shared by multiple clients. This cache is usually based on a server somewhere on the network.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Classification by network location:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;On the browser&lt;/strong&gt;, here the data is stored locally in the browser according to the set HTTP cache specifications.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;On a proxy server&lt;/strong&gt;, either forward or reverse, here the data is stored on a proxy server inside the network according to the set HTTP cache specifications.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;On the origin server&lt;/strong&gt;, here the data is stored on the server where the web application resides. The origin server cache might involve other caches aswell that differ from the HTTP cache (e.g. database cache and others).&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  How does caching looks like from the backend?
&lt;/h2&gt;

&lt;p&gt;For origin server caching, depending on the technology, there could be different approaches to caching both in terms of API and implementation.&lt;/p&gt;

&lt;p&gt;For example, from the perspective of an ASP.NET application, the following are the most common nuances used for caching:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://learn.microsoft.com/en-us/aspnet/core/performance/caching/memory?view=aspnetcore-7.0"&gt;&lt;strong&gt;In-memory caching&lt;/strong&gt;&lt;/a&gt;. The caching location for this is self-explanatory. It works best for affinity caching, when requests from a client are always routed to the same server.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://learn.microsoft.com/en-us/aspnet/core/performance/caching/distributed?view=aspnetcore-7.0"&gt;&lt;strong&gt;Distributed caching&lt;/strong&gt;&lt;/a&gt;. It is best used in non-affinity cache. This works by distributing cached data between servers.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://learn.microsoft.com/en-us/aspnet/core/performance/caching/response?view=aspnetcore-7.0"&gt;&lt;strong&gt;Response caching&lt;/strong&gt;&lt;/a&gt;. Its components, &lt;a href="https://learn.microsoft.com/en-us/aspnet/core/performance/caching/response?view=aspnetcore-7.0#responsecache-attribute"&gt;ResponseCacheAttribute&lt;/a&gt; and &lt;a href="https://learn.microsoft.com/en-us/aspnet/core/performance/caching/middleware?view=aspnetcore-7.0"&gt;Reponse Caching Middleware&lt;/a&gt;, handle cache headers and stores data on the client/proxy server or origin server, according to the HTTP cache specification.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://learn.microsoft.com/en-us/aspnet/core/performance/caching/output?view=aspnetcore-7.0"&gt;&lt;strong&gt;Output caching&lt;/strong&gt;&lt;/a&gt;. This expands on Response Caching Middleware and allows the origin server to store data according to its own specifications.&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;And that, folks, sums it up. If you find these articles valuable and you are interested in more technical discussions or business inquiries, feel free to subscribe or reach out to me!&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;
🤖 &lt;a href="https://www.instagram.com/buffborg/"&gt;Instagram&lt;/a&gt;
&lt;/td&gt;
&lt;td&gt;
💼 &lt;a href="https://www.linkedin.com/in/ion-r%C3%A2peanu-andreescu/"&gt;LinkedIn&lt;/a&gt;
&lt;/td&gt;
&lt;td&gt;
💌 &lt;a href="mailto:ionra.contact@gmail.com"&gt;Email&lt;/a&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Hopefully this has given you a better sense of understanding, or at least refreshed your knowledge of caching and its applications on the web. For further research on this topic, you can start with these:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://httpwg.org/specs/rfc9111.html"&gt;https://httpwg.org/specs/rfc9111.html&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.rfc-editor.org/rfc/rfc9112.html"&gt;https://www.rfc-editor.org/rfc/rfc9112.html&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.rfc-editor.org/rfc/rfc9110.html"&gt;https://www.rfc-editor.org/rfc/rfc9110.html&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://developer.mozilla.org/en-US/docs/Web/HTTP/Caching"&gt;https://developer.mozilla.org/en-US/docs/Web/HTTP/Caching&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.digitalocean.com/community/tutorials/web-caching-basics-terminology-http-headers-and-caching-strategies"&gt;https://www.digitalocean.com/community/tutorials/web-caching-basics-terminology-http-headers-and-caching-strategies&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.mnot.net/cache_docs/#IMP-SERVER"&gt;https://www.mnot.net/cache_docs/#IMP-SERVER&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.c-sharpcorner.com/UploadFile/225740/introduction-of-caching/"&gt;https://www.c-sharpcorner.com/UploadFile/225740/introduction-of-caching/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://learn.microsoft.com/en-us/aspnet/core/performance/caching/overview?view=aspnetcore-7.0"&gt;https://learn.microsoft.com/en-us/aspnet/core/performance/caching/overview?view=aspnetcore-7.0&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>webdev</category>
      <category>http</category>
      <category>caching</category>
      <category>dotnet</category>
    </item>
    <item>
      <title>Concurrency Model in JavaScript Runtime Environments</title>
      <dc:creator>Ion RA</dc:creator>
      <pubDate>Sat, 03 Sep 2022 15:44:21 +0000</pubDate>
      <link>https://dev.to/ionra/concurrency-model-in-javascript-runtime-environments-34dc</link>
      <guid>https://dev.to/ionra/concurrency-model-in-javascript-runtime-environments-34dc</guid>
      <description>&lt;p&gt;For quite some time now, &lt;strong&gt;JavaScript&lt;/strong&gt; (JS) has been the language that brings the Web to life. So it's no surprise that since 2014, of all programming and scripting languages, JavaScript has consistently been the most popular technology among software developers, according to &lt;a href="https://insights.stackoverflow.com/survey" rel="noopener noreferrer"&gt;Stack Overflow surveys&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;As with other programming languages, JavaScript's capabilities are significantly influenced by the runtime environment in which it runs.&lt;/p&gt;

&lt;p&gt;One crucial aspect that depends on runtimes, which is the main topic of this discussion, is the &lt;strong&gt;Concurrency Model&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;In terms of runtimes, &lt;strong&gt;Node.js&lt;/strong&gt; gets the most focus in this discussion, but browsers like &lt;strong&gt;Edge&lt;/strong&gt;, &lt;strong&gt;Firefox&lt;/strong&gt; and others also get decent coverage.&lt;/p&gt;

&lt;p&gt;As for reader's prerequisites general knowledge of programming languages, curiosity and critical thinking are the three most important things to have, as here, besides coding, are also explained and illustrated principles, concepts and designs for achieving concurrency. But those who have a basic knowledge of JS and C/C++ could get a fine-grained analysis of the implementations.&lt;/p&gt;

&lt;p&gt;For all the readers for whom concepts like timers, promises, threads, event loop, asynchronous behavior and others are just an important piece of magic that JS provides, then this post can help you better understand the depths on which different types of concurrency are achieved in JS runtimes. For those who are veterans of these things, you'll enjoy a good old refresher of the concepts . . . or you might just remember the struggles you overcame learning JavaScript 😂 but either way it's still a post worth reading.&lt;/p&gt;

&lt;p&gt;One more thing before we start, doing all this technical "detective" work to understand JS concurrency, depending on the person it might take some time and effort to ponder and understand, so feel free to break it up into several lectures and read it in your own pace. Also don't hesitate to bring imagination and a cheerful spirit while reading this, it will always make things more memorable. I am no comedian, but I'll try to plant some fun here and there along the way, after all . . . why so serious? &lt;/p&gt;

&lt;p&gt;Alright, enough rhetoric, let's get down to business!&lt;/p&gt;

&lt;h2&gt;
  
  
  What is Concurrency? And what is Parallelism?
&lt;/h2&gt;

&lt;blockquote&gt;
&lt;p&gt;Concurrency is about dealing with lots of things at once. Parallelism is about doing lots of things at once. &lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Well, if you are in a hurry you could just resume to the above quote and move further to the next chapter. But if you want to get a little deeper in these concepts keep reading, it rocks 🚀&lt;/p&gt;

&lt;p&gt;First let's clarify a few terminology used here in the context of computer science talk:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;By &lt;strong&gt;execution&lt;/strong&gt; I refer to the process of actualizing instructions scheduled on a central processing unit (CPU)&lt;/li&gt;
&lt;li&gt;A &lt;strong&gt;program&lt;/strong&gt; is a set of instructions and associated data that is kept on computer storage and that can be loaded and executed/run by an operating system.&lt;/li&gt;
&lt;li&gt;A &lt;strong&gt;process&lt;/strong&gt; represents the actual execution of a program containing whatever resources it requires, like CPU, memory and so on.&lt;/li&gt;
&lt;li&gt;By &lt;strong&gt;system&lt;/strong&gt;, in the context of concurrent/parallel system, I refer either to goal-oriented groups of programs, individual programs, or specific areas of a program.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Now, generally speaking, a system that is composed from several parts, is said to be &lt;strong&gt;concurrent&lt;/strong&gt; if: it is able to register progress without needing all its parts to have executed, the order of execution for its constituents could differ and its final result is not influenced by this order. Like, for example, an operating system 🐧 is a pretty common concurrent system. &lt;/p&gt;

&lt;p&gt;A &lt;strong&gt;parallel&lt;/strong&gt; system is just a concurrent system that takes a step forward by having and conditionally enforcing the ability of execution at the same time of multiple of its constituents. Also, most of the times, an operating system would be a good example here, given that it's running on a multi-core machine.&lt;/p&gt;

&lt;p&gt;Ok, now narrowing it down to the program scope, I would add a few more words about the types of program execution:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt; &lt;strong&gt;Synchronous&lt;/strong&gt; execution refers to the execution of a piece of code line by line in a blocking way, that meaning it does not allow the program to deviate from the order of instructions from the piece of code that it is currently running. Think it like a piece of code with a single execution vector/direction that instructions can be ran. This code actually may be even the entire program.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4h0i06arkarl1ist7ljm.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4h0i06arkarl1ist7ljm.png" alt="Image"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Asynchronous&lt;/strong&gt; execution refers to execution of a piece of code that it is not blocking. This usually manifest while invoking subroutines, these are then scheduled to run on the same processing resource after a certain condition is met or they could run on a separate processing resource, in parallel, if the machine allows it. As you might already figured it out, for code to execute this way the program needs to be concurrent.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fwqrfr6rri1od5o96p0i3.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fwqrfr6rri1od5o96p0i3.png" alt="Image"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  What is concurrency needed for?
&lt;/h2&gt;

&lt;p&gt;There are many situations in which some systems need concurrency of some sort for, at least, the appearance of simultaneous execution, in order to preserve a minimum line of acceptance between its users. For example, a user wants to be able to navigate through the web page without feeling lag, that being regardless of what different events it triggers, like opening popup windows, loading images, etc.&lt;/p&gt;

&lt;p&gt;These situations, on the other hand, are likely to be way more prone to lag if they were to happen on synchronous execution. In this case the processing power of the machine it's a much more important factor in determining fluidity of the user experience. For example fetching images may not always resolve fast enough, even if it takes a few seconds this time would be enough to reduce user acceptance. &lt;/p&gt;

&lt;p&gt;Also besides the lag sensation, concurrency, usually parallelism, could be used to increase efficiency and effectiveness of heavy processing programs on multi-core clusters of machines. For example training deep learning models 🤖 could take advantage of a distributed machine cluster.&lt;/p&gt;

&lt;h2&gt;
  
  
  Ok, how is concurrency handled in JavaScript?
&lt;/h2&gt;

&lt;p&gt;Popular JS runtime environments (such as Chrome, Edge, Firefox, Safari, Node.js, Deno, etc.) approach concurrency by first implementing the &lt;strong&gt;event loop&lt;/strong&gt; (EL) concept, than complementing it with a threading technique and lastly using &lt;a href="https://en.wikipedia.org/wiki/Inter-process_communication" rel="noopener noreferrer"&gt;inter-process communication&lt;/a&gt; (IPC). That's it 🎉&lt;/p&gt;

&lt;p&gt;&lt;a href="https://i.giphy.com/media/3o7ypD3Ho7jMArHDxe/giphy.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://i.giphy.com/media/3o7ypD3Ho7jMArHDxe/giphy.gif" alt="GIF"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In the following chapters we will focus mainly on the first two concepts.&lt;/p&gt;

&lt;h2&gt;
  
  
  Where does the event loop come from?
&lt;/h2&gt;

&lt;p&gt;Ok, let's explain this a little. The first reminiscences of the event loop in JS runtime environments date way back to 1995, very long ago when dinosaurs were still a thing and the dot-com bubble had yet to happen. But anyways, it appeared in the private browser Netscape Navigator. About this you can find &lt;a href="https://www.youtube.com/watch?v=Fv9qT9joc0M&amp;amp;t=1841s" rel="noopener noreferrer"&gt;a discussion by Douglas Crockford on the emergence of the event loop&lt;/a&gt; concept in the browser.&lt;/p&gt;

&lt;p&gt;It is important to keep in mind that event loops adhere to a &lt;strong&gt;cooperative&lt;/strong&gt; mode of multitasking, meaning that one piece of code can hand over the baton to another piece of code only intentionally, there is no mediator such as an operating system scheduling agent to manage access to processing resources for each piece of code.&lt;/p&gt;

&lt;h2&gt;
  
  
  What is the general pattern for the Event Loop?
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fm6x8bc4iq62fo6fuccsq.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fm6x8bc4iq62fo6fuccsq.png" alt="Image"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The event loop is a design pattern that is responsible for delegating messages/events from multiple data structures that can be of different types from each other, in a work environment where they can be consumed.&lt;/p&gt;

&lt;p&gt;The EL can be conditioned in order to harden priorities for: starting the loop, pausing the loop, choosing messages or stopping the loop. Until it encounters stop signals or is not forcibly stopped, the event loop in principle will loop forever.&lt;/p&gt;

&lt;h2&gt;
  
  
  How is the event loop implemented in browsers?
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fm5d3yybmq9dh3gegxsq8.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fm5d3yybmq9dh3gegxsq8.png" alt="Image"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Well there is something called The HTML Standard 📄 this dictates the basic specifications that should be followed in the development of browsers. &lt;a href="https://html.spec.whatwg.org/multipage/webappapis.html#event-loop-processing-model" rel="noopener noreferrer"&gt;The execution specifications for the event loop&lt;/a&gt; are also mentioned there, these specifications differ depending on the &lt;a href="https://html.spec.whatwg.org/multipage/webappapis.html#event-loops" rel="noopener noreferrer"&gt;type of event loop&lt;/a&gt;: window event loop (that is the main event loop), worker event loop, worklet event loop. But it is also worth mentioning that not all browsers respect these specifications the same.&lt;/p&gt;

&lt;p&gt;The EL runs on the same thread as the messages it manages. Depending on the browser, the event loop implementation can be done in a separate library, for example browsers like Chrome and Edge that are based on Google's &lt;strong&gt;Chromium&lt;/strong&gt; project use the &lt;a href="https://github.com/libevent/libevent/blob/21e2862689edc59b6265998c4a1a2729552ab0b1/event.c#L1945" rel="noopener noreferrer"&gt;event loop implementation of the libevent library&lt;/a&gt;, on the other hand Firefox seems to use an in-house implementation, that is quite elusive to find but some point of reference it would be found in the &lt;a href="https://searchfox.org/mozilla-central/rev/d34f9713ae128a3138c2b70d8041a535f1049d19/xpcom/threads/SpinEventLoopUntil.h#156" rel="noopener noreferrer"&gt;searchfox repo&lt;/a&gt;. Broadly speaking, event loop implementations are a conditional while loop.&lt;/p&gt;

&lt;h3&gt;
  
  
  Types of operations
&lt;/h3&gt;

&lt;p&gt;When it comes EL operations, there are two main types of them in browsers:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Task&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Microtask&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Besides these two, you could also add the &lt;code&gt;requestAnimationFrame&lt;/code&gt; (rAF) operation for the Window EL, this operation represents the code that is executed before rendering the next frame on the screen. For this reason, it is recommended that in rAF, the code should be related to the visual effects to be rendered. You can watch nice visuals of it and the event loop in &lt;a href="https://youtu.be/cCOL7MC4Pl0?t=748" rel="noopener noreferrer"&gt;Jake Archibald talk at JSConf&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;There are no subtypes of tasks and microtasks. The prioritization for both types in there respective categories is done depending on the moment in which the operation was invoked.&lt;/p&gt;

&lt;h3&gt;
  
  
  The order of operations
&lt;/h3&gt;

&lt;p&gt;As discussed above, broadly speaking, browser operations can be divided into tasks and microtasks.&lt;/p&gt;

&lt;p&gt;The order of operations being:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;A Task&lt;/li&gt;
&lt;li&gt;All Microtasks (including those newly added by the currently running Microtasks, this may clog the EL)&lt;/li&gt;
&lt;li&gt;Pre-rendering (All Animation Callbacks from rAFs, except those added by the rAFs themself)&lt;/li&gt;
&lt;li&gt;Rendering (recognition of the CSS, then the layout by the browser followed by the actual printing of the page).&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The Pre-rendering and rendering parts could actually be skipped if the browsers decides so, often from optimization issues. Also in the case of Worker and Worklet, this operations do not refer to directly accessing the &lt;a href="https://developer.mozilla.org/en-US/docs/Web/API/Document_Object_Model/Introduction" rel="noopener noreferrer"&gt;Document Object Model&lt;/a&gt; (DOM) and its related objects, this not even being allowed, but rather to a virtual canvas specific to each Worker or Worklet.&lt;/p&gt;

&lt;p&gt;Depending on the browser and version, the order of operations may differ more or less from the HTML Standard. But, in general, browsers based on Chromium respect this standard more.&lt;/p&gt;

&lt;h3&gt;
  
  
  Examples of event loop operations in browser
&lt;/h3&gt;

&lt;p&gt;The simple script below should have similar results regardless of which type of EL it runs on:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;workTime&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;mls&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;startDate&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;performance&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;now&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;currentDate&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nx"&gt;currentDate&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;performance&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;now&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;while &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;currentDate&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="nx"&gt;startDate&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="nx"&gt;mls&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;runMicrotask&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Start Microtask&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nf"&gt;workTime&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1000&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nx"&gt;eventLoopPhasesArray&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;index&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Microtask&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Microtask completed&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;runTask&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Start Task&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nf"&gt;workTime&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1000&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nx"&gt;eventLoopPhasesArray&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;index&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Task&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Task completed&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;eventLoopPhasesArray&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;runAnimationCallback&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;eventLoopPhasesArray&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;index&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Animation callback&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Animation callback completed&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nf"&gt;requestAnimationFrame&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;runAnimationCallback&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;eventLoopPhasesArray&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[];&lt;/span&gt;
&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;index&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="nx"&gt;eventLoopPhasesArray&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;index&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Start main script&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Start script task&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="nf"&gt;setTimeout&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;runTask&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nf"&gt;queueMicrotask&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;runMicrotask&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nf"&gt;workTime&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1000&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="nx"&gt;eventLoopPhasesArray&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;index&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;End main script&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Script task completed&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="nf"&gt;requestAnimationFrame&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;runAnimationCallback&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A few observations in here:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Be careful how you try to deduce the order of operations. For example, if you rely on &lt;code&gt;console.log&lt;/code&gt;, you should know that it does not have a standardized implementation and may produce inconsistent results depending on the browser and version.&lt;/li&gt;
&lt;li&gt;Below, the order of operations will be judged using array representation, a web API agnostic method. Each operation has its own string or several characteristic strings that it pushes into an array. Depending on the order of these strings in the array, the order of operations is established. Console.log is still used to exemplify possible misleading due to its non-standardized implementation or potential bugs in the browser.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Firefox results:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fuqhvo674g9el0dex8boa.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fuqhvo674g9el0dex8boa.png" alt="Image"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Edge results:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F2caouu7haui9zd1e88n9.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F2caouu7haui9zd1e88n9.png" alt="Image"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;As I said, the order of execution differs depending on the browser and version. In the above example, Firefox and Edge seem to respect the standard order of execution, in the case of Firefox it seems it is possible to execute several Animation callbacks until it lets go of the next Task and in the case of Edge it seems that rendering operations do not so easily represent a priority over general tasks. Of course you can play with this example, increase the work time for example and see what happens. For sure you could obtain some different scenarios if changes are meaningful enough, but in general both browsers hold up to the standards. Also keep an eye out for &lt;a href="https://developer.mozilla.org/en-US/docs/Web/API/setTimeout#reasons_for_delays_longer_than_specified" rel="noopener noreferrer"&gt;timeouts minimum waiting time and throttling&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Ok, now notice how trying to identify the order of the EL operations after logging with the console API would have been skewed for Firefox. This indicating a run of the animation callback before the script that initiates rAF has been run in the first place. This can be caused by bugs or different implementations of the &lt;a href="https://developer.mozilla.org/en-US/docs/Web/API/Console_API" rel="noopener noreferrer"&gt;console web API&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;It is also important to point out that rAF, an operation related to rendering, is also available in the worker's dedicated global purpose, even if it does not have direct access to the DOM elements in the window 🤔 Now, this may differ depending on the browser and their version, but it is generally possible because a web worker has access to the computation logic for rendering purposes and not to the rendered document and the actual rendering process. Other rendering functionality of web workers is the offscreen rendering API, &lt;a href="https://developer.mozilla.org/en-US/docs/Web/API/OffscreenCanvas" rel="noopener noreferrer"&gt;OffscreenCanvas&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  How is the event loop implemented in Node.js?
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ffkb4k07mwnabbzmgf966.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ffkb4k07mwnabbzmgf966.png" alt="Image"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Aaahh yes, &lt;strong&gt;libuv&lt;/strong&gt;, the Unicorn Velociraptor, or T-Rex, or uhh . . . whatever. This library is responsible for the implementation of EL in Node.js. &lt;a href="https://github.com/libuv/libuv/blob/69ebb2d720ac476248460e1fb3f0f3d10af483dc/src/win/core.c#L592" rel="noopener noreferrer"&gt;The implementation for Windows systems&lt;/a&gt; can be found on GitHub as well as &lt;a href="https://github.com/libuv/libuv/blob/69ebb2d720ac476248460e1fb3f0f3d10af483dc/src/unix/core.c#L372" rel="noopener noreferrer"&gt;the implementation for UNIX systems&lt;/a&gt;. &lt;/p&gt;

&lt;p&gt;In there you can see that these implementations are just a while loop conditioned by certain criteria. In terms of execution, it can be observed that it executes in order a list of different groupings of messages. A difference from the browser is that In this JS runtime, there is only one type of event loop, which means that if worker threads or child processes are spawned, they will all have an event loop that follows the same specifications.&lt;/p&gt;

&lt;p&gt;At the time of writing this article Node.js 16.14.2 is the LTS version and Node.js 18.6.0 is the latest Stable version. From &lt;a href="https://github.com/nodejs/node/commit/af6f1d512db1840bd837e1e8001a22bb7a450a41" rel="noopener noreferrer"&gt;the LTS version onwards, in this commit you can see the last used version of libuv&lt;/a&gt;, i.e. libuv 1.43.0&lt;/p&gt;

&lt;p&gt;Below you can have a look on libuv's basic composition diagram.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fu3tglijbsyyyv9y6rw66.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fu3tglijbsyyyv9y6rw66.png" alt="Image"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Types of operations and their order
&lt;/h3&gt;

&lt;p&gt;&lt;em&gt;Alright now, hold on a minute, you reached about the middle of this article, congrats! Now, just a reminder, if you already spent some good time staring at the screen, probably while sitting on a chair or something, then now it would be a good time to take a minute to relax, get up, go for a walk, stare a little bit into the distance, don't forget to blink and drink your water! Alright? Good!&lt;/em&gt; 🙂&lt;/p&gt;

&lt;p&gt;Getting back to our regular scheduled programming. Unlike the browser, in Node.js there are 4 types of main phases/operations in which you can set callback functions and 2 types of secondary phases, in which you can set callback functions. &lt;/p&gt;

&lt;p&gt;Main phases:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Expired Timers&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;IO tasks&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Immediates&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Close Handlers&lt;/strong&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Secondary phases:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;nextTicks&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;Microtasks (&lt;strong&gt;Promises/queueMicrotask&lt;/strong&gt;)&lt;/li&gt;
&lt;/ol&gt;

&lt;blockquote&gt;
&lt;p&gt;The order is simple, first the main script is executed than it starts looping the main phases in the order they are listed above. At each main phase all of the associated callbacks are executed. Where do the secondary phases come into play, you may ask? Well immediately after the main script is executed and after each execution of one callback from a main phase, all the callbacks from each of the two secondary phases are executed in the order they are listed above.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Take notice that to enter the execution phase of IO tasks, EL does not wait until all immediate callbacks of the previous tick are all executed, especially if there are many of them enqueued.&lt;/p&gt;

&lt;p&gt;In UNIX systems, but also in Windows systems, timer callbacks are stored in a &lt;a href="https://github.com/libuv/libuv/blob/f6dfbcec76f423dfac16e6842f0c8dfd3e91bb92/include/uv/unix.h#L245" rel="noopener noreferrer"&gt;min-heap&lt;/a&gt;, called &lt;a href="https://github.com/libuv/libuv/blob/f6dfbcec76f423dfac16e6842f0c8dfd3e91bb92/include/uv/unix.h#L245" rel="noopener noreferrer"&gt;timer_heap&lt;/a&gt; which is a property of the structure that represents the EL. While the &lt;a href="https://github.com/libuv/libuv/blob/v1.43.0/include/uv/unix.h#L224" rel="noopener noreferrer"&gt;pending IO&lt;/a&gt;, &lt;a href="https://github.com/libuv/libuv/blob/v1.43.0/include/uv/unix.h#L225" rel="noopener noreferrer"&gt;IO poll&lt;/a&gt; and &lt;a href="https://github.com/libuv/libuv/blob/v1.43.0/src/unix/loop.c#L53" rel="noopener noreferrer"&gt;immediate&lt;/a&gt; callbacks are memorized in queue data structures. And the way in which &lt;a href="https://github.com/libuv/libuv/blob/v1.43.0/src/unix/core.c#L212" rel="noopener noreferrer"&gt;close handlers&lt;/a&gt; callbacks are stored denotes the fact that they are also stored in a queue-type data structure.&lt;/p&gt;

&lt;p&gt;The code below shows the complete phases (including those that do not allow you to set callback functions) of the UNIX EL (the Windows ones are similar) from libuv 1.43.0. The comments were removed from code for better representation.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight c"&gt;&lt;code&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="nf"&gt;uv_run&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;uv_loop_t&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;loop&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;uv_run_mode&lt;/span&gt; &lt;span class="n"&gt;mode&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="err"&gt; &lt;/span&gt; &lt;span class="err"&gt; &lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;timeout&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="err"&gt; &lt;/span&gt; &lt;span class="err"&gt; &lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="err"&gt; &lt;/span&gt; &lt;span class="err"&gt; &lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;ran_pending&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="err"&gt; &lt;/span&gt; 
&lt;span class="err"&gt; &lt;/span&gt; &lt;span class="err"&gt; &lt;/span&gt; &lt;span class="n"&gt;r&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;uv__loop_alive&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;loop&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="err"&gt; &lt;/span&gt; &lt;span class="err"&gt; &lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="err"&gt; &lt;/span&gt; &lt;span class="err"&gt; &lt;/span&gt; &lt;span class="err"&gt; &lt;/span&gt; &lt;span class="n"&gt;uv__update_time&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;loop&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="err"&gt; &lt;/span&gt; 
&lt;span class="err"&gt; &lt;/span&gt; &lt;span class="err"&gt; &lt;/span&gt; &lt;span class="k"&gt;while&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;r&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="n"&gt;loop&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;stop_flag&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="err"&gt; &lt;/span&gt; &lt;span class="err"&gt; &lt;/span&gt; &lt;span class="err"&gt; &lt;/span&gt; &lt;span class="n"&gt;uv__update_time&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;loop&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="err"&gt; &lt;/span&gt; &lt;span class="err"&gt; &lt;/span&gt; &lt;span class="err"&gt; &lt;/span&gt; &lt;span class="n"&gt;uv__run_timers&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;loop&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="err"&gt; &lt;/span&gt; &lt;span class="err"&gt; &lt;/span&gt; &lt;span class="err"&gt; &lt;/span&gt; &lt;span class="n"&gt;ran_pending&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;uv__run_pending&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;loop&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="err"&gt; &lt;/span&gt; &lt;span class="err"&gt; &lt;/span&gt; &lt;span class="err"&gt; &lt;/span&gt; &lt;span class="n"&gt;uv__run_idle&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;loop&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="err"&gt; &lt;/span&gt; &lt;span class="err"&gt; &lt;/span&gt; &lt;span class="err"&gt; &lt;/span&gt; &lt;span class="n"&gt;uv__run_prepare&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;loop&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="err"&gt; &lt;/span&gt; 
&lt;span class="err"&gt; &lt;/span&gt; &lt;span class="err"&gt; &lt;/span&gt; &lt;span class="err"&gt; &lt;/span&gt; &lt;span class="n"&gt;timeout&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="err"&gt; &lt;/span&gt; &lt;span class="err"&gt; &lt;/span&gt; &lt;span class="err"&gt; &lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="n"&gt;mode&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="n"&gt;UV_RUN_ONCE&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="n"&gt;ran_pending&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="n"&gt;mode&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="n"&gt;UV_RUN_DEFAULT&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="err"&gt; &lt;/span&gt; &lt;span class="err"&gt; &lt;/span&gt; &lt;span class="err"&gt; &lt;/span&gt; &lt;span class="err"&gt; &lt;/span&gt; &lt;span class="n"&gt;timeout&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;uv_backend_timeout&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;loop&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="err"&gt; &lt;/span&gt; 
&lt;span class="err"&gt; &lt;/span&gt; &lt;span class="err"&gt; &lt;/span&gt; &lt;span class="err"&gt; &lt;/span&gt; &lt;span class="n"&gt;uv__io_poll&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;loop&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;timeout&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="err"&gt; &lt;/span&gt; 
&lt;span class="err"&gt; &lt;/span&gt; &lt;span class="err"&gt; &lt;/span&gt; &lt;span class="err"&gt; &lt;/span&gt; &lt;span class="n"&gt;uv__metrics_update_idle_time&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;loop&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="err"&gt; &lt;/span&gt; 
&lt;span class="err"&gt; &lt;/span&gt; &lt;span class="err"&gt; &lt;/span&gt; &lt;span class="err"&gt; &lt;/span&gt; &lt;span class="n"&gt;uv__run_check&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;loop&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="err"&gt; &lt;/span&gt; &lt;span class="err"&gt; &lt;/span&gt; &lt;span class="err"&gt; &lt;/span&gt; &lt;span class="n"&gt;uv__run_closing_handles&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;loop&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="err"&gt; &lt;/span&gt; 
&lt;span class="err"&gt; &lt;/span&gt; &lt;span class="err"&gt; &lt;/span&gt; &lt;span class="err"&gt; &lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;mode&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="n"&gt;UV_RUN_ONCE&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="err"&gt; &lt;/span&gt; &lt;span class="err"&gt; &lt;/span&gt; &lt;span class="err"&gt; &lt;/span&gt; &lt;span class="err"&gt; &lt;/span&gt; &lt;span class="n"&gt;uv__update_time&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;loop&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="err"&gt; &lt;/span&gt; &lt;span class="err"&gt; &lt;/span&gt; &lt;span class="err"&gt; &lt;/span&gt; &lt;span class="err"&gt; &lt;/span&gt; &lt;span class="n"&gt;uv__run_timers&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;loop&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="err"&gt; &lt;/span&gt; &lt;span class="err"&gt; &lt;/span&gt; &lt;span class="err"&gt; &lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="err"&gt; &lt;/span&gt; 
&lt;span class="err"&gt; &lt;/span&gt; &lt;span class="err"&gt; &lt;/span&gt; &lt;span class="err"&gt; &lt;/span&gt; &lt;span class="n"&gt;r&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;uv__loop_alive&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;loop&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="err"&gt; &lt;/span&gt; &lt;span class="err"&gt; &lt;/span&gt; &lt;span class="err"&gt; &lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;mode&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="n"&gt;UV_RUN_ONCE&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="n"&gt;mode&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="n"&gt;UV_RUN_NOWAIT&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="err"&gt; &lt;/span&gt; &lt;span class="err"&gt; &lt;/span&gt; &lt;span class="err"&gt; &lt;/span&gt; &lt;span class="err"&gt; &lt;/span&gt; &lt;span class="k"&gt;break&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="err"&gt; &lt;/span&gt; &lt;span class="err"&gt; &lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="err"&gt; &lt;/span&gt; 
&lt;span class="err"&gt; &lt;/span&gt; &lt;span class="err"&gt; &lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;loop&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;stop_flag&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="err"&gt; &lt;/span&gt; &lt;span class="err"&gt; &lt;/span&gt; &lt;span class="err"&gt; &lt;/span&gt; &lt;span class="n"&gt;loop&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;stop_flag&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="err"&gt; &lt;/span&gt; 
&lt;span class="err"&gt; &lt;/span&gt; &lt;span class="err"&gt; &lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The 4 main phases are represented by the following functions:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;a href="https://github.com/libuv/libuv/blob/v1.43.0/src/timer.c#L163" rel="noopener noreferrer"&gt;uv__run_timers&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/libuv/libuv/blob/v1.43.0/src/unix/core.c#L806" rel="noopener noreferrer"&gt;uv__run_pending&lt;/a&gt; / &lt;a href="https://github.com/libuv/libuv/blob/v1.43.0/src/unix/epoll.c#L103" rel="noopener noreferrer"&gt;uv__io_poll&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/libuv/libuv/blob/v1.43.0/src/unix/loop-watcher.c#L48" rel="noopener noreferrer"&gt;uv__run_check&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/libuv/libuv/blob/v1.43.0/src/unix/core.c#L312" rel="noopener noreferrer"&gt;uv__run_closing_handles&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Note that the execution order of a Close Handler callback depends on how the close event was issued. That is, it was closed abruptly (such as socket.destroy), then it will be treated regularly by being the last phase that is executed in the event loop, if it was closed in smooth mode (such as server.close), then the close callback will be treated as a &lt;code&gt;nextTick&lt;/code&gt; callback.&lt;/p&gt;

&lt;p&gt;Below is a mention from &lt;a href="https://nodejs.org/en/docs/guides/event-loop-timers-and-nexttick/#close-callbacks" rel="noopener noreferrer"&gt;the official Node.js documentation about close callbacks&lt;/a&gt;:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fcz2sf3nn7vmc64iehgy4.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fcz2sf3nn7vmc64iehgy4.png" alt="Image"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Related to &lt;a href="https://nodejs.org/en/docs/guides/event-loop-timers-and-nexttick/#setimmediate-vs-settimeout" rel="noopener noreferrer"&gt;the differences in the node docs between timers and immediates&lt;/a&gt; the order of execution is not practically deterministic in all possible cases. It appears that determinism appears as soon as we have an IO callback. Since then it is clear that all immediate callbacks will execute first than followed by timer callbacks in the next tick of the loop.&lt;/p&gt;

&lt;p&gt;The execution of callbacks from a queue of a main phase is done, in general, until exhaustion. However, there is also a limit up to which it executes callbacks. After each executed callback of a main phase, EL then runs all the callbacks from the secondary phases until it moves to the next callback from a main phase (&lt;a href="https://github.com/nodejs/node/pull/22842" rel="noopener noreferrer"&gt;this execution relationship between task and microtask has been discussed&lt;/a&gt; to be implemented in nodejs since 2018) .&lt;/p&gt;

&lt;p&gt;Now, things may get a bit more complicated, so strap on to your sits. Even though so far it appeared that the secondary phases belong to the EL, well . . . they actually don't 😲 they are not even once mentioned in libuv, they can be considered add-ons maintaining and extending the general flow of the event loop.&lt;/p&gt;

&lt;p&gt;Wait there is more!&lt;/p&gt;

&lt;p&gt;There needs to be something that links the low level C code of libuv to the high level JS code. Between JS land (that is everything written in JS) and libuv (the C land practically) there is code that makes the binding between the two worlds and that code it resides in the C++ land 🤯 Yes folks you read it right, that is how JS can communicate with C and that is where from JS we can use the microtask and nextTick logic.&lt;/p&gt;

&lt;p&gt;These Node.js bindings are actually quite a broad topic that deserves its own separate discussion. But to keep it short, the C++ ==&amp;gt; JS most significant binding point to highlight how the secondary phases are added on to libuv's EL is represented by the &lt;a href="https://github.com/nodejs/node/blob/v16.14.2/src/api/callback.cc#L166" rel="noopener noreferrer"&gt;InternalMakeCallback&lt;/a&gt; function.&lt;/p&gt;

&lt;p&gt;Basically, this C++ function is where the propagation to the JS land of the execution command for a main phase callback coming from the EL is triggered. And besides that here is also where it's triggered &lt;a href="https://github.com/nodejs/node/blob/v16.14.2/src/api/callback.cc#L219" rel="noopener noreferrer"&gt;the propagation to the JS land of the execution command for all secondary phases callbacks&lt;/a&gt;, but this time coming not from EL, but either from C++ land in case of nextTicks or from the &lt;a href="https://v8.dev/docs" rel="noopener noreferrer"&gt;V8 engine&lt;/a&gt; for promises.&lt;/p&gt;

&lt;p&gt;Finally the code that traverses the these two queues is located in JS Land, in the &lt;a href="https://github.com/nodejs/node/blob/v16.14.2/lib/internal/process/task_queues.js#L68" rel="noopener noreferrer"&gt;processTicksAndRejections&lt;/a&gt; function.&lt;/p&gt;

&lt;p&gt;Libuv is not aware of the presence of any microtask or nextTick queues. Only C++ Land and JS Land are aware of their existence.&lt;/p&gt;

&lt;p&gt;Ok, I know for some of you this might be a little bit hard to keep track of&lt;/p&gt;

&lt;p&gt;&lt;a href="https://i.giphy.com/media/h3Jxu7a7pd72w/giphy.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://i.giphy.com/media/h3Jxu7a7pd72w/giphy.gif" alt="GIF"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;And for good reasons. It actually could be elaborated even further, but I think summarizing it to those things that are most important is enough for the scope of this lecture, after all the binding points, API mappings, their mechanisms of action and whatnot are actually quite numerous.&lt;/p&gt;

&lt;p&gt;Also keep in mind that the current 16.14.2 LTS version gradually received changes for its bindings, so in this regard older versions may differ quite a bit.&lt;/p&gt;

&lt;p&gt;Fortunately for those who are interested to know more, starting from the references presented in here and going towards JS or C, you can actually follow up (or track down 🙃) these bindings by yourself. &lt;/p&gt;

&lt;p&gt;Anyways, it will get easier towards the end, I promise 😉🤞&lt;/p&gt;

&lt;h3&gt;
  
  
  Examples of event loop operations in Node.js
&lt;/h3&gt;

&lt;p&gt;Add the script below in a file, name it whatever, myScript.js if you will, and run it with Node.js. For example &lt;code&gt;node myScript.js&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;fs&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;fs&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;net&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;net&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;

&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;workTime&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;mls&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="err"&gt; &lt;/span&gt; &lt;span class="err"&gt; &lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;startDate&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;performance&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;now&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="err"&gt; &lt;/span&gt; &lt;span class="err"&gt; &lt;/span&gt; &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;currentDate&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="err"&gt; &lt;/span&gt; &lt;span class="err"&gt; &lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="err"&gt; &lt;/span&gt; &lt;span class="err"&gt; &lt;/span&gt; &lt;span class="err"&gt; &lt;/span&gt; &lt;span class="err"&gt; &lt;/span&gt; &lt;span class="nx"&gt;currentDate&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;performance&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;now&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="err"&gt; &lt;/span&gt; &lt;span class="err"&gt; &lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;while &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;currentDate&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="nx"&gt;startDate&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="nx"&gt;mls&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;runTask&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;taskName&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;timeForRunning&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="err"&gt; &lt;/span&gt; &lt;span class="err"&gt; &lt;/span&gt; &lt;span class="nf"&gt;queueNextTickArray&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;nextTickArray&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="err"&gt; &lt;/span&gt; &lt;span class="err"&gt; &lt;/span&gt; &lt;span class="nf"&gt;queueMicrotaskArray&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;microtaskArray&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="err"&gt; &lt;/span&gt; &lt;span class="err"&gt; &lt;/span&gt; &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;timeForRunning&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="err"&gt; &lt;/span&gt; &lt;span class="err"&gt; &lt;/span&gt; &lt;span class="err"&gt; &lt;/span&gt; &lt;span class="err"&gt; &lt;/span&gt; &lt;span class="nf"&gt;workTime&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;timeForRunning&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="err"&gt; &lt;/span&gt; &lt;span class="err"&gt; &lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="err"&gt; &lt;/span&gt; &lt;span class="err"&gt; &lt;/span&gt; 
&lt;span class="err"&gt; &lt;/span&gt; &lt;span class="err"&gt; &lt;/span&gt; &lt;span class="nx"&gt;eventLoopPhasesArray&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;index&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;taskName&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;runTimmer&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="err"&gt; &lt;/span&gt; &lt;span class="err"&gt; &lt;/span&gt; &lt;span class="nf"&gt;runTask&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Timmer&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;500&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;runImmediate&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="err"&gt; &lt;/span&gt; &lt;span class="err"&gt; &lt;/span&gt; &lt;span class="nf"&gt;runTask&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Immediate&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;500&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;runNextTick&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="err"&gt; &lt;/span&gt; &lt;span class="err"&gt; &lt;/span&gt; &lt;span class="nx"&gt;eventLoopPhasesArray&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;index&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Next tick&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;runMicrotask&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="err"&gt; &lt;/span&gt; &lt;span class="err"&gt; &lt;/span&gt; &lt;span class="nx"&gt;eventLoopPhasesArray&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;index&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Microtask&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;runCloseHandler&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="err"&gt; &lt;/span&gt; &lt;span class="err"&gt; &lt;/span&gt; &lt;span class="nf"&gt;runTask&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Close Handler&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;500&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;queueTaskArray&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;taskArray&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;queueFucntion&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="err"&gt; &lt;/span&gt; &lt;span class="err"&gt; &lt;/span&gt; &lt;span class="nx"&gt;taskArray&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;forEach&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;taskCallback&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="err"&gt; &lt;/span&gt; &lt;span class="err"&gt; &lt;/span&gt; &lt;span class="err"&gt; &lt;/span&gt; &lt;span class="err"&gt; &lt;/span&gt; &lt;span class="nf"&gt;queueFucntion&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;taskCallback&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="err"&gt; &lt;/span&gt; &lt;span class="err"&gt; &lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;queueMicrotaskArray&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;microtaskArray&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="err"&gt; &lt;/span&gt; &lt;span class="err"&gt; &lt;/span&gt; &lt;span class="nf"&gt;queueTaskArray&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;microtaskArray&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;queueMicrotask&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;queueNextTickArray&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;nextTickArray&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="err"&gt; &lt;/span&gt; &lt;span class="err"&gt; &lt;/span&gt; &lt;span class="nf"&gt;queueTaskArray&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;nextTickArray&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;nextTick&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;queueTimmerArray&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;timmerArray&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="err"&gt; &lt;/span&gt; &lt;span class="err"&gt; &lt;/span&gt; &lt;span class="nf"&gt;queueTaskArray&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;timmerArray&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setTimeout&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;queueImmediateArray&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;immediateArray&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="err"&gt; &lt;/span&gt; &lt;span class="err"&gt; &lt;/span&gt; &lt;span class="nf"&gt;queueTaskArray&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;immediateArray&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setImmediate&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;queueCloseHandlerArray&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;closeHandlerArray&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="err"&gt; &lt;/span&gt; &lt;span class="err"&gt; &lt;/span&gt; &lt;span class="nf"&gt;queueTaskArray&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;closeHandlerArray&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;closeHandlerCallback&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="err"&gt; &lt;/span&gt; &lt;span class="err"&gt; &lt;/span&gt; &lt;span class="err"&gt; &lt;/span&gt; &lt;span class="err"&gt; &lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;socket&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;net&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;createConnection&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;&lt;span class="na"&gt;port&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;8080&lt;/span&gt;&lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="err"&gt; &lt;/span&gt; &lt;span class="err"&gt; &lt;/span&gt; &lt;span class="err"&gt; &lt;/span&gt; &lt;span class="err"&gt; &lt;/span&gt; &lt;span class="nx"&gt;socket&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;on&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;close&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;closeHandlerCallback&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="err"&gt; &lt;/span&gt; &lt;span class="err"&gt; &lt;/span&gt; &lt;span class="err"&gt; &lt;/span&gt; &lt;span class="err"&gt; &lt;/span&gt; &lt;span class="nx"&gt;socket&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;destroy&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="err"&gt; &lt;/span&gt; &lt;span class="err"&gt; &lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;ioCallback&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;err&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="err"&gt; &lt;/span&gt; &lt;span class="err"&gt; &lt;/span&gt; &lt;span class="nx"&gt;eventLoopPhasesArray&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;index&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;IO&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="err"&gt; &lt;/span&gt; &lt;span class="err"&gt; &lt;/span&gt; &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;err&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="err"&gt; &lt;/span&gt; &lt;span class="err"&gt; &lt;/span&gt; &lt;span class="err"&gt; &lt;/span&gt; &lt;span class="err"&gt; &lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;err&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="err"&gt; &lt;/span&gt; &lt;span class="err"&gt; &lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="err"&gt; &lt;/span&gt; &lt;span class="err"&gt; &lt;/span&gt; &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;loops&lt;/span&gt;&lt;span class="o"&gt;--&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="err"&gt; &lt;/span&gt; &lt;span class="err"&gt; &lt;/span&gt; &lt;span class="err"&gt; &lt;/span&gt; &lt;span class="err"&gt; &lt;/span&gt; &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;eventLoopPhasesArray&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="err"&gt; &lt;/span&gt; &lt;span class="err"&gt; &lt;/span&gt; &lt;span class="err"&gt; &lt;/span&gt; &lt;span class="err"&gt; &lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="err"&gt; &lt;/span&gt; &lt;span class="err"&gt; &lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="err"&gt; &lt;/span&gt; &lt;span class="err"&gt; &lt;/span&gt; &lt;span class="nf"&gt;queueTimmerArray&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;timmerArray&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="err"&gt; &lt;/span&gt; &lt;span class="err"&gt; &lt;/span&gt; &lt;span class="nf"&gt;queueImmediateArray&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;immediateArray&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="err"&gt; &lt;/span&gt; &lt;span class="err"&gt; &lt;/span&gt; &lt;span class="nf"&gt;queueNextTickArray&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;nextTickArray&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="err"&gt; &lt;/span&gt; &lt;span class="err"&gt; &lt;/span&gt; &lt;span class="nf"&gt;queueMicrotaskArray&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;microtaskArray&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="err"&gt; &lt;/span&gt; &lt;span class="err"&gt; &lt;/span&gt; &lt;span class="nf"&gt;queueCloseHandlerArray&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;clsoeHandlerArray&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="err"&gt; &lt;/span&gt; &lt;span class="err"&gt; &lt;/span&gt; &lt;span class="nx"&gt;fs&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;readFile&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;someFileOnYourComputer.txt&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;utf8&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;ioCallback&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;eventLoopPhasesArray&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[];&lt;/span&gt;
&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;index&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;loops&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;timmerArray&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Array&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;fill&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;runTimmer&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;immediateArray&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Array&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;fill&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;runImmediate&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;nextTickArray&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Array&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;fill&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;runNextTick&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;microtaskArray&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Array&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;fill&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;runMicrotask&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;clsoeHandlerArray&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Array&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;fill&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;runCloseHandler&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="nx"&gt;fs&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;readFile&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;someFileOnYourComputer.txt&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;utf8&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;ioCallback&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;So this example is pretty simple, here are a few observations:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;As with the example for browsers, we register the order of operations by adding their name to an array. &lt;/li&gt;
&lt;li&gt;You can pass arrays of callbacks to be synchronously scheduled for each phase of EL, except IO, using &lt;code&gt;queue. . .Array&lt;/code&gt; functions.&lt;/li&gt;
&lt;li&gt;The loop starts with an IO callback, that is to avoid the uncertainty of order from the beginning of the program of timers and immediates.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The result should be similar to the one below:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fx12xfyevd5j6ixp58i5j.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fx12xfyevd5j6ixp58i5j.png" alt="Image"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You can play with this example and test different scenarios. For example you can enqueue a &lt;code&gt;nextTick&lt;/code&gt; callback at the same level with the first &lt;code&gt;fs.readFile&lt;/code&gt; call and see what happens. &lt;/p&gt;

&lt;h2&gt;
  
  
  What are the general principles of multithreading? Something JS specific?
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ftsklm3vk86khm855qjak.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ftsklm3vk86khm855qjak.png" alt="Image"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;As I specified above, JS runtimes complement the concurrent experience of EL with a thread implementation technique. This resulted from the computational necessity of some more demanding tasks in which parallelism through threads proved to be useful. &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;There are also cases in which parallelism needs to be reached by other means, like for example to improve tolerance to failure. Here it comes IPC. To further expand on this subject you can check &lt;a href="https://www.chromium.org/developers/design-documents/multi-process-architecture/" rel="noopener noreferrer"&gt;Chromium's approach&lt;/a&gt; and also &lt;a href="https://blog.mozilla.org/attack-and-defense/2021/04/27/examining-javascript-inter-process-communication-in-firefox/" rel="noopener noreferrer"&gt;Firefox's approach&lt;/a&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;In browsers JS threads are generally known as web workers, and in Node.js they are called worker threads.&lt;/p&gt;

&lt;p&gt;A few bits of theory here. The concurrent nature of a system can be achieved using two models, &lt;a href="https://en.wikipedia.org/wiki/Preemption_(computing)#PREEMPTIVE" rel="noopener noreferrer"&gt;preemptive multitasking&lt;/a&gt; and &lt;a href="https://en.wikipedia.org/wiki/Cooperative_multitasking" rel="noopener noreferrer"&gt;cooperative multitasking&lt;/a&gt;. The later we talked about already, the former it means quite the opposite of the later, that is pieces of code hand on the baton to each other only under the decision of a common supervisor, like the operating system for example.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;With great power comes great responsibility! And that is why programs in Node.js and browsers, whether with or without threads, are exposed to race conditions. You can check &lt;a href="https://www.nodejsdesignpatterns.com/blog/node-js-race-conditions/" rel="noopener noreferrer"&gt;an article by Luciano Mammino about race conditions in JS&lt;/a&gt; for further details on this topic.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Until I get further into the specific details of JS threads, it is also worth mentioning a few laws about the maximum speed that can be reached in paralyzing the execution of a program. In this context, according to the theory, there are several laws, some more practical than others depending on the situation, but all specify how much the execution time of a program can be minimized by reaching an upper limit of performance  through parallelization that it cannot exceed no matter how many more processors are added into the mix. Often the usage of these laws, more for orientation purpose, happens in the architecture point of an application.&lt;/p&gt;

&lt;p&gt;Ok, here they are:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;a href="https://en.wikipedia.org/wiki/Amdahl's_law" rel="noopener noreferrer"&gt;Amdahl's law&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://en.wikipedia.org/wiki/Gustafson%27s_law" rel="noopener noreferrer"&gt;Gustafson's law&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Details about these two are outside the scope of this discussion, but if you want to purse the theory about them you can follow the leads above. &lt;/p&gt;

&lt;p&gt;And one more thing, the multithreading technique, in general, is also supported by the stagnation of the processing speed of only one CPU core. This is something that was observed in &lt;a href="https://en.wikipedia.org/wiki/Moore%27s_law" rel="noopener noreferrer"&gt;Moore's law&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  How does JavaScript work with threads in browser?
&lt;/h2&gt;

&lt;p&gt;In browser, threads are known as &lt;a href="https://developer.mozilla.org/en-US/docs/Web/API/Web_Workers_API" rel="noopener noreferrer"&gt;web workers&lt;/a&gt; and are made available through an internal API.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://html.spec.whatwg.org/multipage/workers.html" rel="noopener noreferrer"&gt;These web workers have general specifications mentioned in the HTML standard&lt;/a&gt; according to which implementations in different browsers are oriented, but depending of browser and version these might slightly differ. Hmm I wonder where have I heard that before 🤔&lt;/p&gt;

&lt;p&gt;In terms of relationship between threads, usually those threads that spawn other threads are called &lt;strong&gt;parent threads&lt;/strong&gt;, and the other ones &lt;strong&gt;child threads&lt;/strong&gt;. Those who are children of same parent are called &lt;strong&gt;sibling threads&lt;/strong&gt;. Pretty straight forward, huh?&lt;/p&gt;

&lt;p&gt;Communication between child threads and the parent thread is done with the help of the &lt;a href="https://developer.mozilla.org/en-US/docs/Web/API/Worker/postMessage" rel="noopener noreferrer"&gt;postMessage&lt;/a&gt; function or &lt;a href="https://developer.mozilla.org/en-US/docs/Web/API/Worker/message_event" rel="noopener noreferrer"&gt;message event&lt;/a&gt; function, which are the access points in an internal &lt;a href="https://developer.mozilla.org/en-US/docs/Web/API/MessageChannel" rel="noopener noreferrer"&gt;MessageChannel&lt;/a&gt; created for communication between parent and child thread.&lt;/p&gt;

&lt;p&gt;You can also create your own MessageChannel instances for communication between threads of any kind and &lt;a href="https://html.spec.whatwg.org/multipage/browsers.html#browsing-context" rel="noopener noreferrer"&gt;browsing contexts&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;There are 3 types of workers in browser:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;a href="https://developer.mozilla.org/en-US/docs/Web/API/DedicatedWorkerGlobalScope" rel="noopener noreferrer"&gt;Dedicated workers&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://developer.mozilla.org/en-US/docs/Web/API/SharedWorker" rel="noopener noreferrer"&gt;Shared workers&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://developer.mozilla.org/en-US/docs/Web/API/Service_Worker_API" rel="noopener noreferrer"&gt;Service workers&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;In terms of composition, according to specifications, when a web worker is created it should receive &lt;a href="https://html.spec.whatwg.org/multipage/workers.html#worker-event-loop" rel="noopener noreferrer"&gt;its own instance of EL&lt;/a&gt; and memory resources separated from the other threads.&lt;/p&gt;

&lt;p&gt;On efficiency side of things, most browsers implement something called thread pool, basically a group of already created threads that can be used for CPU intensive operations. The number of threads in the pool does not have to be very high, as discussed earlier the best effort done in parallel is limited by the hardware. You can check out &lt;a href="https://source.chromium.org/chromium/chromium/src/+/main:base/task/thread_pool.h;l=68" rel="noopener noreferrer"&gt;the thread pool implementation for Chromium browsers&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/mdn/dom-examples/tree/master/web-workers" rel="noopener noreferrer"&gt;Some examples of Web Workers&lt;/a&gt; can be found from MDN.&lt;/p&gt;

&lt;h2&gt;
  
  
  How does JavaScript work with threads in Node.js?
&lt;/h2&gt;

&lt;p&gt;&lt;em&gt;Alright, I guess this is the last lesson. Not much more left to go and you'll witness the true powers of concurrent programming. So, what are you waiting for? Let's do it.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://i.giphy.com/media/3o84sw9CmwYpAnRRni/giphy.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://i.giphy.com/media/3o84sw9CmwYpAnRRni/giphy.gif" alt="GIF"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In Node.js threads can be used with the &lt;strong&gt;worker_threads.js&lt;/strong&gt; module. This have become a stable functionality starting with Node.js 12.15&lt;/p&gt;

&lt;p&gt;Regarding composition, each worker thread has its own instance of V8 engine with queues for microtasks and their own &lt;strong&gt;memory heap&lt;/strong&gt;, plus their own instance of libuv event loop.&lt;/p&gt;

&lt;p&gt;Just like browsers, in order to make working with threads more efficient Node.js also supports the thread pool concept.&lt;/p&gt;

&lt;p&gt;In Node.js communication between threads can be done in an asynchronous 2-way-communication style by using &lt;code&gt;MessageChannel&lt;/code&gt; objects.&lt;/p&gt;

&lt;p&gt;A few more words about data passing. There are 3 ways to pass data between threads:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Cloning data&lt;/li&gt;
&lt;li&gt;Transfer (could be done with &lt;code&gt;ArrayBuffer&lt;/code&gt;, &lt;code&gt;MessagePort&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;Shared data (with &lt;code&gt;SharedArrayBuffer&lt;/code&gt;)&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;A quick tip here, the &lt;a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Atomics" rel="noopener noreferrer"&gt;Atomics Module&lt;/a&gt; can be used to synchronize shared data. It is already integrated since Node.js version 16 LTS onwards ⬆️ and in modern browsers as well.&lt;/p&gt;

&lt;p&gt;In terms of bindings, the creation and initiation of threads starts from the JS land with the &lt;a href="https://github.com/nodejs/node/blob/v16.14.2/lib/internal/worker.js" rel="noopener noreferrer"&gt;worker.js&lt;/a&gt; file. The Worker class from JS Land is linked in the C++ land to the file &lt;a href="https://github.com/nodejs/node/blob/v16.14.2/src/node_worker.cc" rel="noopener noreferrer"&gt;node_worker.cc&lt;/a&gt;, by &lt;a href="https://github.com/nodejs/node/blob/v16.14.2/lib/internal/worker.js#L185" rel="noopener noreferrer"&gt;calling a constructor called WorkerImpl&lt;/a&gt;, which &lt;a href="https://github.com/nodejs/node/blob/v16.14.2/lib/internal/worker.js#L65" rel="noopener noreferrer"&gt;is a bounding point to C++ land&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Going back to worker composition, in node_worker.cc you can actually see how new resources are allocated for the thread, such as the parent &lt;code&gt;MessagePort&lt;/code&gt;, its own libuv EL, its own Heap, an isolated V8 engine, etc.&lt;/p&gt;

&lt;p&gt;Access from user land (that is whatever JS files written by the users) is provided by &lt;code&gt;worker_threads&lt;/code&gt; module exports, we know that. But regarding communication concepts besides &lt;code&gt;MessagePort&lt;/code&gt; and other similar constructs, &lt;a href="https://github.com/nodejs/node/blob/v16.14.2/lib/internal/worker/io.js#L28" rel="noopener noreferrer"&gt;MessageChannel is also available by being imported in worker/io.js file&lt;/a&gt;. This is actually a bounding point to C++ land by being associated to the &lt;a href="https://github.com/nodejs/node/blob/v16.14.2/src/node_messaging.cc#L1411" rel="noopener noreferrer"&gt;MessageChannel function&lt;/a&gt; from the &lt;a href="https://github.com/nodejs/node/blob/v16.14.2/src/node_messaging.cc" rel="noopener noreferrer"&gt;node_messaging.cc&lt;/a&gt; file.&lt;/p&gt;

&lt;p&gt;Now, thread initiation, that includes resource allocation, is started at the moment of creation with &lt;code&gt;new Worker(. . .)&lt;/code&gt;. This Worker constructor implementation resides in worker.js file, and when &lt;a href="https://github.com/nodejs/node/blob/v16.14.2/lib/internal/worker.js#L259" rel="noopener noreferrer"&gt;this[kHandle].startThread() it's called inside it&lt;/a&gt; it will activate a binding point to C++ land by calling to its association &lt;a href="https://github.com/nodejs/node/blob/v16.14.2/src/node_worker.cc#L579" rel="noopener noreferrer"&gt; the StartThread function&lt;/a&gt; from node_worker.cc which ends up doing all the dirty work for us 😎&lt;/p&gt;

&lt;p&gt;Finally, the actual execution of the script by the newly created thread starts in the &lt;a href="https://github.com/nodejs/node/blob/v16.14.2/lib/internal/main/worker_thread.js" rel="noopener noreferrer"&gt;worker_threrad.js&lt;/a&gt; file. More precisely &lt;a href="https://github.com/nodejs/node/blob/v16.14.2/lib/internal/main/worker_thread.js#L104" rel="noopener noreferrer"&gt;when the script it's loaded in there&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://i.giphy.com/media/Quh1CAKOTRCl9VVU3f/giphy.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://i.giphy.com/media/Quh1CAKOTRCl9VVU3f/giphy.gif" alt="GIF"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Examples of operations with worker threads
&lt;/h3&gt;

&lt;p&gt;Below is the script file to be ran:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;Worker&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;MessageChannel&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;worker_threads&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;worker1&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Worker&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;./workerScript.js&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;worker2&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Worker&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;./workerScript.js&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;port1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;port2&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;MessageChannel&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

&lt;span class="nx"&gt;worker1&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;on&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;message&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;message&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="err"&gt; &lt;/span&gt; &lt;span class="err"&gt; &lt;/span&gt; &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`MAIN THREAD: Message from child worker [id: &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;worker1&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;threadId&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;] is "&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;message&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="nx"&gt;worker2&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;on&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;message&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;message&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="err"&gt; &lt;/span&gt; &lt;span class="err"&gt; &lt;/span&gt; &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`MAIN THREAD: Message from child worker [id: &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;worker2&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;threadId&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;] is "&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;message&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="nx"&gt;worker1&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;postMessage&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;&lt;span class="na"&gt;port&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;port1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;worker1&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;threadId&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;siblingId&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;worker2&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;threadId&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;port1&lt;/span&gt;&lt;span class="p"&gt;]);&lt;/span&gt;
&lt;span class="nx"&gt;worker2&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;postMessage&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;&lt;span class="na"&gt;port&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;port2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;worker2&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;threadId&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;siblingId&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;worker1&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;threadId&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;port2&lt;/span&gt;&lt;span class="p"&gt;]);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And below is the workerScript.js file:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;parentPort&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;worker_threads&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;

&lt;span class="nx"&gt;parentPort&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;on&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;message&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;message&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="err"&gt; &lt;/span&gt; &lt;span class="err"&gt; &lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;port&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;siblingId&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;message&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="err"&gt; &lt;/span&gt; &lt;span class="err"&gt; &lt;/span&gt; &lt;span class="nx"&gt;parentPort&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;postMessage&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Got the channel details&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="err"&gt; &lt;/span&gt; &lt;span class="err"&gt; &lt;/span&gt; &lt;span class="nx"&gt;port&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;on&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;message&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;message&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="err"&gt; &lt;/span&gt; &lt;span class="err"&gt; &lt;/span&gt; &lt;span class="err"&gt; &lt;/span&gt; &lt;span class="err"&gt; &lt;/span&gt; &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`WORKER THREAD[ID: &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;]: Message from sibling worker [id: &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;siblingId&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;] is "&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;message&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="err"&gt; &lt;/span&gt; &lt;span class="err"&gt; &lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="err"&gt; &lt;/span&gt; &lt;span class="err"&gt; &lt;/span&gt; &lt;span class="nx"&gt;port&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;postMessage&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Hakuna Matata!&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A few words about what this code is supposed to do:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The parent thread creates two child threads that are supposed to talk between each other.&lt;/li&gt;
&lt;li&gt;To do so it also creates a &lt;code&gt;MessageChannel&lt;/code&gt; whose ports it transfers, one each, to the child threads.&lt;/li&gt;
&lt;li&gt;Then the siblings can talk with each other.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The result should be similar to the one below, the order does not have to be the same.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F6u8hcy16s4r8pnc2fuam.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F6u8hcy16s4r8pnc2fuam.png" alt="Image"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Feel free to play around with this example. Maybe try using one file for all threads, see how you can do that. &lt;/p&gt;

&lt;p&gt;&lt;em&gt;Hint: you may need to use the &lt;code&gt;isMainThread&lt;/code&gt; property.&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;And that pretty much sums it up folks. Of course, there are more things to talk about on this topic, but that can be for another time.&lt;/p&gt;

&lt;p&gt;Most importantly, you now not only have a good understanding of the big picture of concurrency in JS runtimes and how it all comes together, but you also have good leads and know where to look 🔎&lt;/p&gt;

&lt;p&gt;And last, but certainly not least, thank you for your interest in software engineering!&lt;/p&gt;

&lt;h2&gt;
  
  
  References
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://nodejs.org/docs/latest-v16.x/api/index.html" rel="noopener noreferrer"&gt;https://nodejs.org/docs/latest-v16.x/api/index.html&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/nodejs/node/tree/v16.14.2" rel="noopener noreferrer"&gt;https://github.com/nodejs/node/tree/v16.14.2&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://docs.libuv.org/en/v1.x" rel="noopener noreferrer"&gt;http://docs.libuv.org/en/v1.x&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/libuv/libuv/tree/v1.43.0" rel="noopener noreferrer"&gt;https://github.com/libuv/libuv/tree/v1.43.0&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://nikhilm.github.io/uvbook/index.html" rel="noopener noreferrer"&gt;https://nikhilm.github.io/uvbook/index.html&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://libevent.org/" rel="noopener noreferrer"&gt;https://libevent.org/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://searchfox.org/mozilla-central/source/" rel="noopener noreferrer"&gt;https://searchfox.org/mozilla-central/source/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/chromium/chromium" rel="noopener noreferrer"&gt;https://github.com/chromium/chromium&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/libevent/libevent" rel="noopener noreferrer"&gt;https://github.com/libevent/libevent&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.nodejsdesignpatterns.com/" rel="noopener noreferrer"&gt;https://www.nodejsdesignpatterns.com/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://firefox-source-docs.mozilla.org/" rel="noopener noreferrer"&gt;https://firefox-source-docs.mozilla.org/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.chromium.org/developers/" rel="noopener noreferrer"&gt;https://www.chromium.org/developers/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://v8.dev/docs" rel="noopener noreferrer"&gt;https://v8.dev/docs&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://spidermonkey.dev/docs/" rel="noopener noreferrer"&gt;https://spidermonkey.dev/docs/&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>javascript</category>
      <category>node</category>
      <category>programming</category>
      <category>concurrency</category>
    </item>
  </channel>
</rss>
