<?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: Supratik Das</title>
    <description>The latest articles on DEV Community by Supratik Das (@supratikdas01).</description>
    <link>https://dev.to/supratikdas01</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.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3971720%2F47140e67-9cd9-4cea-b7ca-c3f181568b02.jpeg</url>
      <title>DEV Community: Supratik Das</title>
      <link>https://dev.to/supratikdas01</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/supratikdas01"/>
    <language>en</language>
    <item>
      <title>[Boost]</title>
      <dc:creator>Supratik Das</dc:creator>
      <pubDate>Fri, 26 Jun 2026 16:11:21 +0000</pubDate>
      <link>https://dev.to/supratikdas01/-59ok</link>
      <guid>https://dev.to/supratikdas01/-59ok</guid>
      <description>&lt;div class="ltag__link--embedded"&gt;
  &lt;div class="crayons-story "&gt;
  &lt;a href="https://dev.to/supratikdas01/why-do-promises-run-before-settimeout-explained-visually-gdf" class="crayons-story__hidden-navigation-link"&gt;Why Do Promises Run Before setTimeout? (Explained Visually)&lt;/a&gt;


  &lt;div class="crayons-story__body crayons-story__body-full_post"&gt;
    &lt;div class="crayons-story__top"&gt;
      &lt;div class="crayons-story__meta"&gt;
        &lt;div class="crayons-story__author-pic"&gt;

          &lt;a href="/supratikdas01" class="crayons-avatar  crayons-avatar--l  "&gt;
            &lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3971720%2F47140e67-9cd9-4cea-b7ca-c3f181568b02.jpeg" alt="supratikdas01 profile" class="crayons-avatar__image" width="800" height="878"&gt;
          &lt;/a&gt;
        &lt;/div&gt;
        &lt;div&gt;
          &lt;div&gt;
            &lt;a href="/supratikdas01" class="crayons-story__secondary fw-medium m:hidden"&gt;
              Supratik Das
            &lt;/a&gt;
            &lt;div class="profile-preview-card relative mb-4 s:mb-0 fw-medium hidden m:inline-block"&gt;
              
                Supratik Das
                
              
              &lt;div id="story-author-preview-content-3990869" class="profile-preview-card__content crayons-dropdown branded-7 p-4 pt-0"&gt;
                &lt;div class="gap-4 grid"&gt;
                  &lt;div class="-mt-4"&gt;
                    &lt;a href="/supratikdas01" class="flex"&gt;
                      &lt;span class="crayons-avatar crayons-avatar--xl mr-2 shrink-0"&gt;
                        &lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3971720%2F47140e67-9cd9-4cea-b7ca-c3f181568b02.jpeg" class="crayons-avatar__image" alt="" width="800" height="878"&gt;
                      &lt;/span&gt;
                      &lt;span class="crayons-link crayons-subtitle-2 mt-5"&gt;Supratik Das&lt;/span&gt;
                    &lt;/a&gt;
                  &lt;/div&gt;
                  &lt;div class="print-hidden"&gt;
                    
                      Follow
                    
                  &lt;/div&gt;
                  &lt;div class="author-preview-metadata-container"&gt;&lt;/div&gt;
                &lt;/div&gt;
              &lt;/div&gt;
            &lt;/div&gt;

          &lt;/div&gt;
          &lt;a href="https://dev.to/supratikdas01/why-do-promises-run-before-settimeout-explained-visually-gdf" class="crayons-story__tertiary fs-xs"&gt;&lt;time&gt;Jun 25&lt;/time&gt;&lt;span class="time-ago-indicator-initial-placeholder"&gt;&lt;/span&gt;&lt;/a&gt;
        &lt;/div&gt;
      &lt;/div&gt;

    &lt;/div&gt;

    &lt;div class="crayons-story__indention"&gt;
      &lt;h2 class="crayons-story__title crayons-story__title-full_post"&gt;
        &lt;a href="https://dev.to/supratikdas01/why-do-promises-run-before-settimeout-explained-visually-gdf" id="article-link-3990869"&gt;
          Why Do Promises Run Before setTimeout? (Explained Visually)
        &lt;/a&gt;
      &lt;/h2&gt;
        &lt;div class="crayons-story__tags"&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/javascript"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;javascript&lt;/a&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/webdev"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;webdev&lt;/a&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/beginners"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;beginners&lt;/a&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/tutorial"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;tutorial&lt;/a&gt;
        &lt;/div&gt;
      &lt;div class="crayons-story__bottom"&gt;
        &lt;div class="crayons-story__details"&gt;
          &lt;a href="https://dev.to/supratikdas01/why-do-promises-run-before-settimeout-explained-visually-gdf" class="crayons-btn crayons-btn--s crayons-btn--ghost crayons-btn--icon-left"&gt;
            &lt;div class="multiple_reactions_aggregate"&gt;
              &lt;span class="multiple_reactions_icons_container"&gt;
                  &lt;span class="crayons_icon_container"&gt;
                    &lt;img src="https://assets.dev.to/assets/exploding-head-daceb38d627e6ae9b730f36a1e390fca556a4289d5a41abb2c35068ad3e2c4b5.svg" width="24" height="24"&gt;
                  &lt;/span&gt;
                  &lt;span class="crayons_icon_container"&gt;
                    &lt;img src="https://assets.dev.to/assets/sparkle-heart-5f9bee3767e18deb1bb725290cb151c25234768a0e9a2bd39370c382d02920cf.svg" width="24" height="24"&gt;
                  &lt;/span&gt;
              &lt;/span&gt;
              &lt;span class="aggregate_reactions_counter"&gt;2&lt;span class="hidden s:inline"&gt;&amp;nbsp;reactions&lt;/span&gt;&lt;/span&gt;
            &lt;/div&gt;
          &lt;/a&gt;
            &lt;a href="https://dev.to/supratikdas01/why-do-promises-run-before-settimeout-explained-visually-gdf#comments" class="crayons-btn crayons-btn--s crayons-btn--ghost crayons-btn--icon-left flex items-center"&gt;
              

              &lt;span class="hidden s:inline"&gt;Add&amp;nbsp;Comment&lt;/span&gt;
            &lt;/a&gt;
        &lt;/div&gt;
        &lt;div class="crayons-story__save"&gt;
          &lt;small class="crayons-story__tertiary fs-xs mr-2"&gt;
            4 min read
          &lt;/small&gt;
            
              &lt;span class="bm-initial crayons-icon c-btn__icon"&gt;
                

              &lt;/span&gt;
              &lt;span class="bm-success crayons-icon c-btn__icon"&gt;
                

              &lt;/span&gt;
            
        &lt;/div&gt;
      &lt;/div&gt;
    &lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;

&lt;/div&gt;


</description>
    </item>
    <item>
      <title>Why Do Promises Run Before setTimeout? (Explained Visually)</title>
      <dc:creator>Supratik Das</dc:creator>
      <pubDate>Thu, 25 Jun 2026 16:45:11 +0000</pubDate>
      <link>https://dev.to/supratikdas01/why-do-promises-run-before-settimeout-explained-visually-gdf</link>
      <guid>https://dev.to/supratikdas01/why-do-promises-run-before-settimeout-explained-visually-gdf</guid>
      <description>&lt;p&gt;Almost every JavaScript developer has seen this:&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="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&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="o"&gt;=&amp;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;setTimeout&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="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="nb"&gt;Promise&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;resolve&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;then&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="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;Promise&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;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;End&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Output&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Start
End
Promise
setTimeout
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;At first glance, this seems strange.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;setTimeout(..., 0)&lt;/code&gt; looks like it should execute immediately. So why does the Promise callback run first?&lt;/p&gt;

&lt;p&gt;The answer lies in &lt;strong&gt;JavaScript's Event Loop&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;👉 &lt;a href="https://www.jsvisualizer.bytefront.dev/?code=console.log(%22Start%22)%3B%0A%0AsetTimeout(()%20%3D%3E%20%7B%0A%20%20console.log(%22setTimeout%22)%3B%0A%7D%2C%200)%3B%0A%0APromise.resolve().then(()%20%3D%3E%20%7B%0A%20%20console.log(%22Promise%22)%3B%0A%7D)%3B%0A%0Aconsole.log(%22End%22)%3B" rel="noopener noreferrer"&gt;Run this in JS Visualizer — watch the queues in real time&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  Step 1: JavaScript Executes Synchronous Code First
&lt;/h2&gt;

&lt;p&gt;Everything in the current script executes on the &lt;strong&gt;Call Stack&lt;/strong&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="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&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;prints immediately.&lt;/p&gt;

&lt;p&gt;When JavaScript encounters:&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="nf"&gt;setTimeout&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="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;setTimeout&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="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;it &lt;strong&gt;does not execute the callback&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Instead, it hands the callback to the browser (or Node.js) timer system and continues executing the current script.&lt;/p&gt;

&lt;p&gt;Next:&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="nb"&gt;Promise&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;resolve&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;then&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="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;Promise&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;The Promise is already resolved, so its &lt;code&gt;.then()&lt;/code&gt; callback is immediately scheduled in the &lt;strong&gt;Microtask Queue&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Finally:&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="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;End&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;prints.&lt;/p&gt;

&lt;p&gt;Current output:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Start
End
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Step 2: The Call Stack Becomes Empty
&lt;/h2&gt;

&lt;p&gt;At this point:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Microtask Queue
---------------
Promise callback

Task Queue (Macrotask Queue)
----------------------------
setTimeout callback
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Step 3: The Event Loop Rule
&lt;/h2&gt;

&lt;p&gt;The Event Loop always follows this order:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Execute one Task (current script).&lt;/li&gt;
&lt;li&gt;Empty the &lt;strong&gt;entire Microtask Queue&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Optionally allow rendering.&lt;/li&gt;
&lt;li&gt;Execute the next Task (Macrotask).&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Because Promise callbacks are &lt;strong&gt;Microtasks&lt;/strong&gt;, they execute before timer callbacks.&lt;/p&gt;

&lt;p&gt;Output now becomes:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Start
End
Promise
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Step 4: Finally, &lt;code&gt;setTimeout&lt;/code&gt; Runs
&lt;/h2&gt;

&lt;p&gt;After the Microtask Queue is empty, the Event Loop processes the next Task:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;setTimeout
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Final output:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Start
End
Promise
setTimeout
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Common Misconception
&lt;/h2&gt;

&lt;p&gt;❌ &lt;strong&gt;Promises have higher priority than setTimeout.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;This is an oversimplification.&lt;/p&gt;

&lt;p&gt;✅ The real reason is:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;The Event Loop &lt;strong&gt;must completely drain the Microtask Queue before executing the next Task (Macrotask).&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  Why Doesn't &lt;code&gt;setTimeout(0)&lt;/code&gt; Run Immediately?
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;setTimeout(fn, 0)&lt;/code&gt; means:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Execute &lt;strong&gt;after at least&lt;/strong&gt; 0 milliseconds.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;It does &lt;strong&gt;not&lt;/strong&gt; mean "execute instantly."&lt;/p&gt;

&lt;p&gt;Even after the timer expires, its callback waits until:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The current script finishes.&lt;/li&gt;
&lt;li&gt;The Call Stack becomes empty.&lt;/li&gt;
&lt;li&gt;Every pending Microtask has completed.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Visual Timeline
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Current Script
│
├── console.log("Start")
├── setTimeout(...)  ─────► Browser Timer
├── Promise.then() ───────► Microtask Queue
└── console.log("End")

Call Stack Empty
        │
        ▼
Drain ALL Microtasks
        │
        ▼
Promise callback

        ▼
Run Next Task
        │
        ▼
setTimeout callback
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Example 2
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&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="mi"&gt;1&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="o"&gt;=&amp;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="mi"&gt;2&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="nb"&gt;Promise&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;resolve&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
  &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;then&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;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="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
  &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;then&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;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="mi"&gt;4&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="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Output&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;1
5
3
4
2
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Why?
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Synchronous → 1, 5
Microtasks  → 3, 4
Tasks       → 2
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The second &lt;code&gt;.then()&lt;/code&gt; is also a Microtask, so it executes before &lt;code&gt;setTimeout&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;👉 &lt;a href="https://www.jsvisualizer.bytefront.dev/?code=console.log(1)%3B%0A%0AsetTimeout(()%20%3D%3E%20console.log(2)%2C%200)%3B%0A%0APromise.resolve()%0A%20%20.then(()%20%3D%3E%20console.log(3))%0A%20%20.then(()%20%3D%3E%20console.log(4))%3B%0A%0Aconsole.log(5)%3B" rel="noopener noreferrer"&gt;Run Example 2 in JS Visualizer&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  Example 3
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&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&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="o"&gt;=&amp;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;Timeout&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="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="nb"&gt;Promise&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;resolve&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;then&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="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;Promise 1&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="nb"&gt;Promise&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;resolve&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;then&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="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;Promise 2&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="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;End&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Output&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Start
End
Promise 1
Promise 2
Timeout
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;While executing &lt;code&gt;Promise 1&lt;/code&gt;, another Microtask is scheduled. The Event Loop continues draining Microtasks until none remain.&lt;/p&gt;

&lt;p&gt;👉 &lt;a href="https://www.jsvisualizer.bytefront.dev/?code=console.log(%22Start%22)%3B%0A%0AsetTimeout(()%20%3D%3E%20%7B%0A%20%20console.log(%22Timeout%22)%3B%0A%7D%2C%200)%3B%0A%0APromise.resolve().then(()%20%3D%3E%20%7B%0A%20%20console.log(%22Promise%201%22)%3B%0A%0A%20%20Promise.resolve().then(()%20%3D%3E%20%7B%0A%20%20%20%20console.log(%22Promise%202%22)%3B%0A%20%20%7D)%3B%0A%7D)%3B%0A%0Aconsole.log(%22End%22)%3B" rel="noopener noreferrer"&gt;Run Example 3 in JS Visualizer&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  Microtask Starvation
&lt;/h2&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;loop&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nb"&gt;Promise&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;resolve&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;then&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;loop&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nf"&gt;loop&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Because every Microtask schedules another Microtask:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;setTimeout&lt;/code&gt; never executes.&lt;/li&gt;
&lt;li&gt;Rendering may be blocked.&lt;/li&gt;
&lt;li&gt;The application appears frozen.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This is called &lt;strong&gt;Microtask Starvation&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;👉 &lt;a href="https://www.jsvisualizer.bytefront.dev/?code=let%20count%20%3D%200%3B%0A%0Afunction%20loop()%20%7B%0A%20%20if%20(count%2B%2B%20%3C%205)%20%7B%0A%20%20%20%20console.log(%22microtask%22%2C%20count)%3B%0A%20%20%20%20Promise.resolve().then(loop)%3B%0A%20%20%7D%0A%7D%0A%0AsetTimeout(()%20%3D%3E%20console.log(%22setTimeout%20(waited)%22)%2C%200)%3B%0Aloop()%3B" rel="noopener noreferrer"&gt;Run Microtask Starvation in JS Visualizer&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Note: The starvation example uses a counter limit so it doesn't actually freeze your browser — but you'll see all microtasks drain before the setTimeout fires.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  Mental Model
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Current Script
      ↓
Drain ALL Microtasks
      ↓
Browser may Render
      ↓
Run ONE Task
      ↓
Repeat
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Key Takeaways
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;setTimeout(..., 0)&lt;/code&gt; schedules a &lt;strong&gt;Task (Macrotask)&lt;/strong&gt; after &lt;strong&gt;at least&lt;/strong&gt; the specified delay.&lt;/li&gt;
&lt;li&gt;Promise callbacks (&lt;code&gt;then&lt;/code&gt;, &lt;code&gt;catch&lt;/code&gt;, &lt;code&gt;finally&lt;/code&gt;) are &lt;strong&gt;Microtasks&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;The Event Loop always drains the &lt;strong&gt;entire Microtask Queue&lt;/strong&gt; before processing the next Task.&lt;/li&gt;
&lt;li&gt;This is why Promises execute before &lt;code&gt;setTimeout()&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Microtasks can enqueue more Microtasks, and they all finish before the next Task.&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;Want to see all of this animate live? &lt;strong&gt;&lt;a href="https://www.jsvisualizer.bytefront.dev/" rel="noopener noreferrer"&gt;Open JS Visualizer — free, no signup&lt;/a&gt;&lt;/strong&gt; and step through any example above.&lt;/p&gt;

&lt;p&gt;Related reads:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.jsvisualizer.bytefront.dev/blogs/javascript-event-loop-explained" rel="noopener noreferrer"&gt;JavaScript Event Loop Explained — A Visual, Step-by-Step Guide&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.jsvisualizer.bytefront.dev/blogs/microtask-vs-macrotask-javascript" rel="noopener noreferrer"&gt;Microtask vs Macrotask in JavaScript: The Complete Guide&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>javascript</category>
      <category>webdev</category>
      <category>beginners</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>JavaScript Event Loop Explained — A Visual, Step-by-Step Guide</title>
      <dc:creator>Supratik Das</dc:creator>
      <pubDate>Sat, 06 Jun 2026 19:22:47 +0000</pubDate>
      <link>https://dev.to/supratikdas01/javascript-event-loop-explained-a-visual-step-by-step-guide-27ie</link>
      <guid>https://dev.to/supratikdas01/javascript-event-loop-explained-a-visual-step-by-step-guide-27ie</guid>
      <description>&lt;p&gt;Ask ten developers how the JavaScript event loop works, and you'll get eleven different answers. That's because the event loop is &lt;em&gt;invisible&lt;/em&gt;. You can't console.log it. You can't set a breakpoint on it. You just have to &lt;em&gt;know&lt;/em&gt; it's there, orchestrating everything.&lt;/p&gt;

&lt;p&gt;This guide changes that. We'll walk through the event loop step by step, with code you can actually run and &lt;em&gt;see&lt;/em&gt; in &lt;a href="https://www.jsvisualizer.bytefront.dev" rel="noopener noreferrer"&gt;JS Visualizer&lt;/a&gt; — watching functions enter the call stack, callbacks move through Web APIs, and promises flush from the microtask queue.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Puzzle That Trips Everyone Up
&lt;/h2&gt;

&lt;p&gt;Before we dive in, try to predict the output of this code:&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="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="s1"&gt;A&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="o"&gt;=&amp;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="s1"&gt;B&lt;/span&gt;&lt;span class="dl"&gt;'&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="nb"&gt;Promise&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;resolve&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;then&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;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="s1"&gt;C&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="s1"&gt;D&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Most beginners guess &lt;code&gt;A, B, C, D&lt;/code&gt;. The actual output is:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;A
D
C
B
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If that surprises you, you're in exactly the right place. By the end of this article, you'll understand &lt;em&gt;why&lt;/em&gt; — and it will feel obvious.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;👉 &lt;a href="https://www.jsvisualizer.bytefront.dev/?code=console.log(%27A%27)%3B%0A%0AsetTimeout(()%20%3D%3E%20console.log(%27B%27)%2C%200)%3B%0A%0APromise.resolve().then(()%20%3D%3E%20console.log(%27C%27))%3B%0A%0Aconsole.log(%27D%27)%3B" rel="noopener noreferrer"&gt;Run this puzzle in JS Visualizer&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  The JavaScript Runtime: Four Moving Parts
&lt;/h2&gt;

&lt;p&gt;JavaScript's runtime has four key components:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Component&lt;/th&gt;
&lt;th&gt;Role&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Call Stack&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Where functions execute. One at a time — JS is single-threaded.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Web APIs&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Browser features (setTimeout, fetch, DOM events) running outside the main thread.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Task Queue&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Callbacks from Web APIs waiting for the call stack to empty.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Microtask Queue&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Promise callbacks. Always processed before the task queue.&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;And then there's the &lt;strong&gt;event loop&lt;/strong&gt; itself — the coordinator. Its job: when the call stack is empty, pick the next thing to run.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 1: The Call Stack — One Thing at a Time
&lt;/h2&gt;

&lt;p&gt;JavaScript is single-threaded. It has &lt;strong&gt;one call stack&lt;/strong&gt; and can do &lt;strong&gt;one thing at a time&lt;/strong&gt;. When you call a function, it gets pushed onto the stack. When it returns, it gets popped off.&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;greet&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Hello, &lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;name&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;processUser&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;name&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;message&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;greet&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;name&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;message&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nf"&gt;processUser&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Supratik&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here's what happens on the call stack:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;code&gt;processUser('Supratik')&lt;/code&gt; is pushed onto the stack&lt;/li&gt;
&lt;li&gt;Inside it, &lt;code&gt;greet('Supratik')&lt;/code&gt; is pushed on top&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;greet&lt;/code&gt; returns → popped off the stack&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;console.log(message)&lt;/code&gt; is pushed, executes, popped&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;processUser&lt;/code&gt; returns → popped off. Stack is empty.&lt;/li&gt;
&lt;/ol&gt;

&lt;blockquote&gt;
&lt;p&gt;💡 The call stack is like a stack of plates. You can only add or remove from the top. If a function calls another function, the new one goes on top and must finish before we return to the one below it.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Step 2: Web APIs — Where Async Things Wait
&lt;/h2&gt;

&lt;p&gt;When you call &lt;code&gt;setTimeout&lt;/code&gt;, &lt;code&gt;fetch&lt;/code&gt;, or add a DOM event listener, JavaScript doesn't handle the waiting itself. It hands the job off to &lt;strong&gt;Web APIs&lt;/strong&gt; — features provided by the browser (or Node.js runtime).&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="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="s1"&gt;Start&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="o"&gt;=&amp;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="s1"&gt;Timer done&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="mi"&gt;2000&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="s1"&gt;End&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here's the flow:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;code&gt;console.log('Start')&lt;/code&gt; → runs immediately on the call stack&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;setTimeout&lt;/code&gt; → registers the callback with the Web API. The timer starts counting &lt;em&gt;outside&lt;/em&gt; the call stack. setTimeout itself returns immediately.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;console.log('End')&lt;/code&gt; → runs immediately&lt;/li&gt;
&lt;li&gt;After 2000ms, the Web API moves the callback to the &lt;strong&gt;task queue&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;The event loop sees the call stack is empty → picks the callback → runs it&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Output: &lt;code&gt;Start → End → Timer done&lt;/code&gt;. The timer callback runs &lt;em&gt;last&lt;/em&gt;, even though it was registered second.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;👉 &lt;a href="https://www.jsvisualizer.bytefront.dev/?code=console.log(%27Start%27)%3B%0A%0AsetTimeout(()%20%3D%3E%20%7B%0A%20%20console.log(%27Timer%20done%27)%3B%0A%7D%2C%202000)%3B%0A%0Aconsole.log(%27End%27)%3B" rel="noopener noreferrer"&gt;Watch the timer move through Web APIs&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 3: The Task Queue (Macrotask Queue)
&lt;/h2&gt;

&lt;p&gt;When a Web API finishes its work (timer expires, fetch returns, click happens), it doesn't interrupt whatever's currently running. Instead, it places the callback in the &lt;strong&gt;task queue&lt;/strong&gt; (also called the macrotask queue).&lt;/p&gt;

&lt;p&gt;The event loop's rule is simple: &lt;em&gt;when the call stack is empty, take the first task from the queue and push it onto the stack.&lt;/em&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="nf"&gt;setTimeout&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;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="s1"&gt;First timeout&lt;/span&gt;&lt;span class="dl"&gt;'&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;setTimeout&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;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="s1"&gt;Second timeout&lt;/span&gt;&lt;span class="dl"&gt;'&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="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="s1"&gt;Synchronous&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Output: &lt;code&gt;Synchronous → First timeout → Second timeout&lt;/code&gt;. Both timeouts go to the task queue, and they're processed in order — but only after all synchronous code finishes.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;⚠️ &lt;strong&gt;Common mistake:&lt;/strong&gt; &lt;code&gt;setTimeout(fn, 0)&lt;/code&gt; does NOT mean "run immediately." It means "run as soon as the call stack is empty and you get to the front of the queue." If there's a lot of synchronous code running, the 0ms timer could wait hundreds of milliseconds.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Step 4: The Microtask Queue — Promises Jump the Line
&lt;/h2&gt;

&lt;p&gt;This is where most developers get confused. There are actually &lt;strong&gt;two queues&lt;/strong&gt;, and one has priority over the other.&lt;/p&gt;

&lt;p&gt;The &lt;strong&gt;microtask queue&lt;/strong&gt; holds callbacks from:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;Promise.then()&lt;/code&gt;, &lt;code&gt;.catch()&lt;/code&gt;, &lt;code&gt;.finally()&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;&lt;code&gt;queueMicrotask()&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;MutationObserver&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;The critical rule:&lt;/strong&gt; the event loop drains the &lt;em&gt;entire&lt;/em&gt; microtask queue before touching the task queue. Every. Single. Time. If a microtask adds another microtask, that runs too — before any setTimeout callback gets a chance.&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="nf"&gt;setTimeout&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;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="s1"&gt;Macrotask&lt;/span&gt;&lt;span class="dl"&gt;'&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="nb"&gt;Promise&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;resolve&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;then&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;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="s1"&gt;Microtask 1&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
&lt;span class="nb"&gt;Promise&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;resolve&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;then&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;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="s1"&gt;Microtask 2&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="s1"&gt;Synchronous&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Output:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Synchronous
Microtask 1
Microtask 2
Macrotask
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Even though setTimeout was registered first, both Promise callbacks run before it. The microtask queue always gets priority.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;👉 &lt;a href="https://www.jsvisualizer.bytefront.dev/?code=setTimeout(()%20%3D%3E%20console.log(%27Macrotask%27)%2C%200)%3B%0A%0APromise.resolve().then(()%20%3D%3E%20console.log(%27Microtask%201%27))%3B%0APromise.resolve().then(()%20%3D%3E%20console.log(%27Microtask%202%27))%3B%0A%0Aconsole.log(%27Synchronous%27)%3B" rel="noopener noreferrer"&gt;Watch microtasks jump the line&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 5: The Event Loop Algorithm
&lt;/h2&gt;

&lt;p&gt;Now we can state the event loop's actual algorithm:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Run all &lt;strong&gt;synchronous code&lt;/strong&gt; on the call stack until it's empty.&lt;/li&gt;
&lt;li&gt;Drain the &lt;strong&gt;entire microtask queue&lt;/strong&gt;. If any microtask adds new microtasks, drain those too.&lt;/li&gt;
&lt;li&gt;Take &lt;strong&gt;one task&lt;/strong&gt; from the &lt;strong&gt;task queue&lt;/strong&gt; and push it onto the call stack.&lt;/li&gt;
&lt;li&gt;Go back to step 2. (Yes — microtasks are checked again after every single macrotask.)&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;That's it. The entire event loop is these four steps, on repeat, forever.&lt;/p&gt;

&lt;h2&gt;
  
  
  Solving the Original Puzzle
&lt;/h2&gt;

&lt;p&gt;Now let's go back to our puzzle and trace through it:&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="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="s1"&gt;A&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;           &lt;span class="c1"&gt;// 1. Synchronous → runs immediately&lt;/span&gt;
&lt;span class="nf"&gt;setTimeout&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;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="s1"&gt;B&lt;/span&gt;&lt;span class="dl"&gt;'&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="c1"&gt;// 2. Registers with Web API → callback goes to TASK queue&lt;/span&gt;
&lt;span class="nb"&gt;Promise&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;resolve&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;then&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt;
  &lt;span class="o"&gt;=&amp;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="s1"&gt;C&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;     &lt;span class="c1"&gt;// 3. Already resolved → callback goes to MICROTASK queue&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="s1"&gt;D&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;           &lt;span class="c1"&gt;// 4. Synchronous → runs immediately&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Step by step:&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;code&gt;console.log('A')&lt;/code&gt; → prints &lt;strong&gt;A&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;setTimeout&lt;/code&gt; → callback sent to Web API → moves to task queue&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;Promise.resolve().then()&lt;/code&gt; → already resolved → callback goes to microtask queue&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;console.log('D')&lt;/code&gt; → prints &lt;strong&gt;D&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Call stack is empty → drain microtask queue → &lt;code&gt;console.log('C')&lt;/code&gt; → prints &lt;strong&gt;C&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Microtask queue empty → take from task queue → &lt;code&gt;console.log('B')&lt;/code&gt; → prints &lt;strong&gt;B&lt;/strong&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Final output: &lt;strong&gt;A, D, C, B&lt;/strong&gt;. Mystery solved.&lt;/p&gt;

&lt;h2&gt;
  
  
  Bonus: How async/await Fits In
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;async/await&lt;/code&gt; is just syntactic sugar over Promises. When you &lt;code&gt;await&lt;/code&gt; something, everything after the await becomes a &lt;em&gt;microtask&lt;/em&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;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;demo&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="s1"&gt;Before await&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nb"&gt;Promise&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;resolve&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="s1"&gt;After await&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;  &lt;span class="c1"&gt;// This is a microtask!&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="s1"&gt;Start&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nf"&gt;demo&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="s1"&gt;End&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Output:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Start
Before await
End
After await
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;"After await" runs as a microtask — same as if you'd written &lt;code&gt;Promise.resolve().then(() =&amp;gt; console.log('After await'))&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;👉 &lt;a href="https://www.jsvisualizer.bytefront.dev/?code=async%20function%20demo()%20%7B%0A%20%20console.log(%27Before%20await%27)%3B%0A%20%20await%20Promise.resolve()%3B%0A%20%20console.log(%27After%20await%27)%3B%0A%7D%0A%0Aconsole.log(%27Start%27)%3B%0Ademo()%3B%0Aconsole.log(%27End%27)%3B" rel="noopener noreferrer"&gt;See async/await as microtasks&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Common Mistakes and Misconceptions
&lt;/h2&gt;

&lt;p&gt;❌ &lt;strong&gt;Myth: setTimeout(fn, 0) runs immediately&lt;/strong&gt;&lt;br&gt;
It runs after all synchronous code AND all microtasks. The 0 is a minimum delay, not a guarantee.&lt;/p&gt;

&lt;p&gt;❌ &lt;strong&gt;Myth: Promises are asynchronous&lt;/strong&gt;&lt;br&gt;
The Promise &lt;em&gt;constructor&lt;/em&gt; runs synchronously. Only the &lt;code&gt;.then()&lt;/code&gt; callback is deferred (as a microtask).&lt;/p&gt;

&lt;p&gt;❌ &lt;strong&gt;Myth: JavaScript is multi-threaded because it can do async things&lt;/strong&gt;&lt;br&gt;
JavaScript itself is single-threaded. Web APIs (provided by the browser) can run in parallel, but your JS code always runs one line at a time on one call stack.&lt;/p&gt;
&lt;h2&gt;
  
  
  Summary
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;JavaScript has one call stack&lt;/strong&gt; — it's single-threaded.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Async operations&lt;/strong&gt; (timers, network) are handled by Web APIs outside the main thread.&lt;/li&gt;
&lt;li&gt;When Web APIs finish, callbacks go to the &lt;strong&gt;task queue&lt;/strong&gt; (macrotask queue).&lt;/li&gt;
&lt;li&gt;Promise callbacks go to the &lt;strong&gt;microtask queue&lt;/strong&gt;, which has higher priority.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The event loop:&lt;/strong&gt; run sync code → drain all microtasks → pick one macrotask → repeat.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;async/await&lt;/strong&gt; is syntactic sugar — everything after &lt;code&gt;await&lt;/code&gt; becomes a microtask.&lt;/li&gt;
&lt;/ol&gt;



&lt;p&gt;The best way to internalize this? &lt;strong&gt;See it happen.&lt;/strong&gt; Open &lt;a href="https://www.jsvisualizer.bytefront.dev" rel="noopener noreferrer"&gt;JS Visualizer&lt;/a&gt;, paste any code snippet from this article, and watch every step unfold across the call stack, queues, and event loop — in real time. It's free.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.jsvisualizer.bytefront.dev" class="crayons-btn crayons-btn--primary" rel="noopener noreferrer"&gt;Try JS Visualizer — Free&lt;/a&gt;
&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>webdev</category>
      <category>beginners</category>
      <category>tutorial</category>
    </item>
  </channel>
</rss>
