<?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: Altamash Ali</title>
    <description>The latest articles on DEV Community by Altamash Ali (@altamashali).</description>
    <link>https://dev.to/altamashali</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%2F638177%2Fd5756be4-5953-47cd-8591-312d5177c31b.png</url>
      <title>DEV Community: Altamash Ali</title>
      <link>https://dev.to/altamashali</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/altamashali"/>
    <language>en</language>
    <item>
      <title>Learning Javascript Promise Patterns</title>
      <dc:creator>Altamash Ali</dc:creator>
      <pubDate>Thu, 09 Jun 2022 05:19:20 +0000</pubDate>
      <link>https://dev.to/altamashali/learning-javascript-promise-patterns-11ao</link>
      <guid>https://dev.to/altamashali/learning-javascript-promise-patterns-11ao</guid>
      <description>&lt;p&gt;Hello There!&lt;/p&gt;

&lt;p&gt;Let's learn some advance Javascript promise techniques to write more efficient and reliable JS Code :)&lt;/p&gt;




&lt;p&gt;&lt;u&gt;&lt;strong&gt;1. Fetching multiple independent resources&lt;/strong&gt;&lt;/u&gt;&lt;/p&gt;

&lt;p&gt;consider you have function that fetches a post by ID.&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;const&lt;/span&gt; &lt;span class="nx"&gt;getPostById&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;async&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="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
   &lt;span class="k"&gt;try&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="c1"&gt;// make an async call to fetch the post&lt;/span&gt;
      &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;post&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;loadPost&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="p"&gt;...&lt;/span&gt;
      &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;post&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
   &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;catch&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="c1"&gt;// handle error&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;Now if we have to fetch details of multiple posts:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;const postIds = [1, 2, 3, 4, ...]&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;We can do something like 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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;getPosts&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;postIds&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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;posts&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[];&lt;/span&gt;
  &lt;span class="k"&gt;for&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;id&lt;/span&gt; &lt;span class="k"&gt;of&lt;/span&gt; &lt;span class="nx"&gt;postIds&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;post&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;getPostById&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="c1"&gt;// do processing&lt;/span&gt;
    &lt;span class="p"&gt;...&lt;/span&gt;
    &lt;span class="nx"&gt;posts&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;push&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;post&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="nx"&gt;posts&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;Wait a minute! There is a problem here. The problem is &lt;code&gt;await&lt;/code&gt; keyword will pause the loop until it gets a response from &lt;code&gt;getPostById()&lt;/code&gt;. Fetching each post by Id is an independent operation and result of multiple requests doesn't depend on each other's response. It doesn't make much sense to wait to fetch next post only after previous post has been fetched.&lt;/p&gt;

&lt;p&gt;Let's talk how to resolve this issue. What we can do is make multiple requests concurrently and wait for all of them to get fetched or resolved.&lt;/p&gt;

&lt;p&gt;Javascript provides two promise APIs to handle multiple requests concurrently:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;Promise.all(...)&lt;/code&gt; and &lt;code&gt;Promise.allSettled(...)&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;u&gt;Using &lt;code&gt;Promise.all(...)&lt;/code&gt;&lt;/u&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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;getPosts&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;postIds&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="k"&gt;try&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;postPromises&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;postIds&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;map&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;getPostById&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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;posts&lt;/span&gt; &lt;span class="o"&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="nx"&gt;all&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;postPromises&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
   &lt;span class="c1"&gt;// do processing&lt;/span&gt;
   &lt;span class="p"&gt;...&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;posts&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;catch&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="c1"&gt;// handle error&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;Now, good thing is we are not waiting for previous post request to finish to make request for next one instead now concurrent requests will be fired independent of each other and we are waiting until all posts has been fetched. But there is still one issue here. If one of the promises rejects, &lt;code&gt;Promise.all(...)&lt;/code&gt; immediately rejects, causing every other post not to load. We can improvise it by using &lt;code&gt;Promise.allSettled(...)&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;Promise.allSettled(...)&lt;/code&gt; returns a pending promise that resolves when all of the given promises have been settled either resolved or rejected. This behaviour is very useful to track multiple tasks that are not dependent on one another to complete.&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;const&lt;/span&gt; &lt;span class="nx"&gt;getPosts&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;postIds&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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;postPromises&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;postIds&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;map&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;getPostById&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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;posts&lt;/span&gt; &lt;span class="o"&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="nx"&gt;allSettled&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;postPromises&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="c1"&gt;// outcome of each promise has a status property.&lt;/span&gt;
    &lt;span class="c1"&gt;// If success, it will have value property&lt;/span&gt;
    &lt;span class="c1"&gt;// If fails, it will have reason property&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;posts&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;reduce&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;result&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;post&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="k"&gt;if&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;post&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;status&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;fulfilled&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;result&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;successfullyFetchedPosts&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;push&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;post&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nx"&gt;result&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;failedPosts&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;push&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;post&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;reason&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="nx"&gt;result&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="na"&gt;successfullyFetchedPosts&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[],&lt;/span&gt;
     &lt;span class="na"&gt;failedPosts&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="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// using this function&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;successfullyFetchedPosts&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; 
  &lt;span class="nx"&gt;failedPosts&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;getPosts&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;Promise returned by &lt;code&gt;Promise.allSettled(...)&lt;/code&gt; will almost always be fulfilled. The promise will only reject if we pass a value that is not iterable.&lt;/p&gt;




&lt;p&gt;&lt;u&gt;&lt;strong&gt;2. Avoiding single point of failure using &lt;code&gt;Promise.any(...)&lt;/code&gt;&lt;/strong&gt;&lt;/u&gt;&lt;/p&gt;

&lt;p&gt;Sometimes, we have to fetch some critical resource like financial market data from external APIs. If the API is down, the app will stop working. The &lt;code&gt;Promise.any(...)&lt;/code&gt; is extremely useful in this regard. It enables us to request data from multiple sources ( APIs) and use the result of the first successful promise.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;Promise.any(...)&lt;/code&gt; returns a pending promise that resolves asynchronously as soon as one of the promises in the given iterable fulfils.&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;const&lt;/span&gt; &lt;span class="nx"&gt;promises&lt;/span&gt; &lt;span class="o"&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="nx"&gt;reject&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="nx"&gt;resolve&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;span class="nb"&gt;Promise&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;reject&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="nx"&gt;any&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;promises&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;then&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="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;// 5&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Consider we have three APIs to fetch a resource. We can use &lt;code&gt;Promise.any(...)&lt;/code&gt; like 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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;apis&lt;/span&gt; &lt;span class="o"&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;https://api1/resource/10&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;https://api2/resource/10&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;https://api3/resource/10&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;fetchData&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="nx"&gt;api&lt;/span&gt; &lt;span class="o"&gt;=&amp;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;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;fetch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;api&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;ok&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="nx"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;json&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="nx"&gt;reject&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;some error&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;const&lt;/span&gt; &lt;span class="nx"&gt;getResource&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;Promise&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;any&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="nx"&gt;apis&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;map&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;api&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;fetchData&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;api&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="nx"&gt;getResource&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nx"&gt;then&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;response&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c1"&gt;// process response&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;Promise.any(...)&lt;/code&gt; allows you to improve the performance of critical applications by using the data from the API that responds first. Also it allows you to improve reliability of the application as even if one of the APIs fails, it will continue working as expected. &lt;code&gt;Promise.any(...)&lt;/code&gt; will only reject when all the promises passed as the argument reject.&lt;/p&gt;




&lt;p&gt;&lt;u&gt;&lt;strong&gt;3. Enforcing a time limit for async operations using &lt;code&gt;Promise.race(...)&lt;/code&gt;&lt;/strong&gt;&lt;br&gt;
&lt;/u&gt;&lt;/p&gt;

&lt;p&gt;Suppose we are fetching some resource from an external API. User Interface will be in the loading state until we get response from the API. Sometimes, APIs take a lot of time to give response back to the client and user will be waiting for it , looking at the loading spinner like forever. A better user experience would be to timeout the request after a given number of milliseconds and show error in the UI like request time out. We can easily do this using &lt;code&gt;Promise.race(...)&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;Promise.race(...)&lt;/code&gt; is somewhat similar to &lt;code&gt;Promise.any(...) as both get settled whenever first promise in the iterable settles&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;Promise.race(...)&lt;/code&gt; settles as soon as one of the promises rejects. . &lt;/p&gt;

&lt;p&gt;&lt;code&gt;Promise.any(...)&lt;/code&gt; resolves as soon as one of the promises fulfils. &lt;/p&gt;

&lt;p&gt;&lt;code&gt;Promise.race(...)&lt;/code&gt; rejects if the first promise  that settles is rejected while &lt;code&gt;Promise.any(...)&lt;/code&gt; rejects when all the given promises reject.&lt;/p&gt;

&lt;p&gt;let's implement timeout of the request:&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;const&lt;/span&gt; &lt;span class="nx"&gt;getData&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;async&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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;TIMEOUT_MS&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;2000&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// IN MILLISECONDS&lt;/span&gt;

    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;request&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;fetch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;API_URL&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// actual request&lt;/span&gt;

    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;timeout&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nb"&gt;Promise&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;_&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;reject&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;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;reject&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nb"&gt;Error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Request time out!&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)),&lt;/span&gt; &lt;span class="nx"&gt;TIMEOUT_MS&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt; &lt;span class="c1"&gt;// rejects after 2000 milliseconds&lt;/span&gt;

    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nb"&gt;Promise&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;race&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="nx"&gt;request&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;timeout&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;&lt;u&gt;&lt;strong&gt;4. Batching async requests using &lt;code&gt;Promise.race(...)&lt;/code&gt;&lt;/strong&gt;&lt;/u&gt;&lt;/p&gt;

&lt;p&gt;An interesting use case of &lt;code&gt;Promise.race(...)&lt;/code&gt; is to batch async request. Here is the simple implementation:&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="cm"&gt;/**
 * 
 * @param {{limit: number, concurrentBatches: number}} batchOptions 
 */&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;performRequestBatching&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="nx"&gt;batchOptions&lt;/span&gt; &lt;span class="o"&gt;=&amp;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;query&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="na"&gt;offset&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="na"&gt;limit&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;batchOptions&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;limit&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;batch&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;promises&lt;/span&gt; &lt;span class="o"&gt;=&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;batch&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;model&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;findAll&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;query&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="nx"&gt;query&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;offset&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="nx"&gt;batchOptions&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;limit&lt;/span&gt;&lt;span class="p"&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;batch&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;length&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;promise&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;performLongRequestForBatch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;batch&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&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="c1"&gt;// remove the promise from promises list once it is resolved&lt;/span&gt;
                &lt;span class="nx"&gt;promises&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;promises&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;filter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;p&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;p&lt;/span&gt; &lt;span class="o"&gt;!==&lt;/span&gt; &lt;span class="nx"&gt;promise&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
            &lt;span class="p"&gt;});&lt;/span&gt;
            &lt;span class="nx"&gt;promises&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;push&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;promise&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
            &lt;span class="c1"&gt;// if promises length is greater than provided max concurrent batches&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;promise&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;=&lt;/span&gt; &lt;span class="nx"&gt;batchOptions&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;concurrentBatches&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="c1"&gt;// then wait for any promise to get resolved&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="nx"&gt;race&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;promises&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="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;batch&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="c1"&gt;// wait for remaining batches to finish&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nb"&gt;Promise&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;all&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;promises&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// using batching&lt;/span&gt;
&lt;span class="nx"&gt;batchRequest&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;limit&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;concurrentBatches&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;span class="p"&gt;})&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;p&gt;&lt;strong&gt;Conclusion&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Hurray! That's it. We have learnt multiple patterns related to Javascript promise api like handling multiple request efficiently using &lt;code&gt;Promise.all&lt;/code&gt; and &lt;code&gt;Promise.allSettled&lt;/code&gt;, avoiding SPOF using &lt;code&gt;Promise.any&lt;/code&gt;, timing out async request for better user experience and batching multiple requests using &lt;code&gt;Promise.race&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Please like the post if you have learnt something new :). Also Feel free to point-out or provide suggestions in the comment section if there is some mistake in the post.&lt;/p&gt;

&lt;p&gt;Happy Coding !&lt;/p&gt;

&lt;p&gt;See you!&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>webdev</category>
      <category>node</category>
      <category>react</category>
    </item>
    <item>
      <title>Node.js Event Loop In Action</title>
      <dc:creator>Altamash Ali</dc:creator>
      <pubDate>Sun, 14 Nov 2021 07:20:22 +0000</pubDate>
      <link>https://dev.to/altamashali/nodejs-event-loop-in-action-d5o</link>
      <guid>https://dev.to/altamashali/nodejs-event-loop-in-action-d5o</guid>
      <description>&lt;p&gt;In my last post(&lt;a href="https://dev.to/altamashali/deep-dive-into-nodejs-architecture-5190"&gt;Deep dive into Node.js Architecture&lt;/a&gt;), we learnt about the internals of Node.js and how multiple asynchronous operations work efficiently in a single-threaded environment. We also talked about how event loop works and facilitates the event-driven architecture of Node.js. I would recommend going through my previous post before reading this one.&lt;/p&gt;

&lt;p&gt;In this article, we are going to learn more about event loop and it's different phases along with a code example.&lt;/p&gt;

&lt;p&gt;Before we start, you might ask why does a Node.js developer need to know about Event loop. The answer to this is:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;event loop is the one that handles all the scheduling of your application code and any misconceptions regarding this can lead to poor performance and buggy code,&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;and it is a very important interview question if you are applying for Nodejs backend role.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;so, Let's start :)&lt;/p&gt;

&lt;p&gt;As we discussed earlier, Event loop is nothing but a loop. It just loops over the set of events sent by Synchronous Event Demultiplexer, trigger callbacks and move the application along. &lt;/p&gt;

&lt;h2&gt;
  
  
  Event Loop Phases
&lt;/h2&gt;

&lt;p&gt;The event loop has several different phases to it and each one of these phases maintains a queue of callbacks that are to be executed. Callbacks are destined for different phases based on how they are used by the application.&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%2Ftg3gnbnntwdmdbvutpgo.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%2Ftg3gnbnntwdmdbvutpgo.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h5&gt;
  
  
  Poll
&lt;/h5&gt;

&lt;ul&gt;
&lt;li&gt;The poll phase executes I/O-related callbacks.&lt;/li&gt;
&lt;li&gt;Most of the application code executes in this phase.&lt;/li&gt;
&lt;li&gt;Starting point of Node.js application&lt;/li&gt;
&lt;/ul&gt;

&lt;h5&gt;
  
  
  Check
&lt;/h5&gt;

&lt;ul&gt;
&lt;li&gt;In this phase, callbacks that are triggered via &lt;code&gt;setImmediate()&lt;/code&gt; are executed.&lt;/li&gt;
&lt;/ul&gt;

&lt;h5&gt;
  
  
  Close
&lt;/h5&gt;

&lt;ul&gt;
&lt;li&gt;This phase executes callbacks triggered via &lt;code&gt;EventEmitter close events&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;For example, when a net.Server TCP server closes, it emits a close events that runs in this phase.&lt;/li&gt;
&lt;/ul&gt;

&lt;h5&gt;
  
  
  Timers
&lt;/h5&gt;

&lt;ul&gt;
&lt;li&gt;In this phase, callbacks triggered via &lt;code&gt;setTimeout()&lt;/code&gt; and &lt;code&gt;setInterval()&lt;/code&gt; are executed.&lt;/li&gt;
&lt;/ul&gt;

&lt;h5&gt;
  
  
  Pending
&lt;/h5&gt;

&lt;ul&gt;
&lt;li&gt;Special system events are run in this phase, like when a net.Socket TCP soccer throws an &lt;code&gt;ECONNREFUSED&lt;/code&gt; error.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Apart from these, there are &lt;strong&gt;two special microtask queues&lt;/strong&gt; that can have callbacks added to them while a phase is running.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;The first microtask queue handles callbacks registered using &lt;code&gt;process.nextTick()&lt;/code&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The second microtask queues handles &lt;code&gt;promises&lt;/code&gt; that reject or resolve.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  Execution Priority and order
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Callback in the microtask queues take priority over callbacks in the phase's normal queue.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Callbacks in the next tick microtask queue run before callbacks in the promise microtask queue.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;When the application starts running, the event loop is also started and the phases are handled one at a time. Node.js adds callbacks to different queues as appropriate while the application runs&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;When the event loop gets to a phase, it will run all the callbacks in the phase's queue. Once all the callbacks in a given phase are executed, the event loop then moves on to the next phase.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Let's see one code example:&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%2Fij235b1f7tffh8rphneu.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%2Fij235b1f7tffh8rphneu.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Output will be : 8, 3, 2, 1,  4, 7, 6, 5&lt;/p&gt;

&lt;p&gt;Let's see what is happening behind the scene:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Code execution starts off executing line by line in the poll phase.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;First, the fs module is required.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Next, the &lt;code&gt;setImmediate()&lt;/code&gt; call is run and its callback is added to the &lt;code&gt;check queue&lt;/code&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Next, the &lt;code&gt;promise&lt;/code&gt; resolves, adding callback to the &lt;code&gt;promise microtask queue&lt;/code&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Then, &lt;code&gt;process.nextTick()&lt;/code&gt; runs next, adding its callback to the &lt;code&gt;next tick microtask queue&lt;/code&gt;. &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Next, the &lt;code&gt;fs.readFile()&lt;/code&gt; tells Node.js to start reading the file, placing its callback in the &lt;code&gt;poll queue&lt;/code&gt; once it is ready.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Finally &lt;code&gt;console.log(8)&lt;/code&gt; is called and 8 is printed to the screen.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That's it for the current stack.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Now, the two microtask queues are consulted. The next tick microtask queue is always checked first, and callback 3 is called. Since, there is only one callback in the next tick microtask queue, the promise microtask queue is checked next and callback 2 is executed. That finished the two micro-task queues and the current poll phase is completed.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Now, the event loop enters the check phase. This phase has callback 1 in it, which is then executed. Both the microtask queues are empty at this point, so the check phase ends.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The close phase is checked next but is empty, so the loop continues. The same happens with the timers phase and the pending phase, and the event loop continues back around to the poll phase.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Once it is back in the poll phase, the application doesn't have much else going on, so it basically waits until the file has finished being read. Once that happens, the &lt;code&gt;fs.readFile()&lt;/code&gt; callback is run.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;The number 4 is immediately printed since it's the first line in the callback.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;next, the &lt;code&gt;setTimeout()&lt;/code&gt; call is made and callback 5 is added to the timers queue.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The &lt;code&gt;setImmediate()&lt;/code&gt; call happens next, adding callback 6 to the check queue.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Finally, the process.nextTick() call is made, adding callback 7 to the next ticket microtask queue.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The poll phase is now finished and the microtask queues are again consulted. &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Callback 7 runs from the next tick queue,&lt;/li&gt;
&lt;li&gt;&lt;p&gt;the promise queue is consulted and found empty, and the poll phase ends.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Again the event loop enters to the check phase where callback 6 is encountered. The number is printed and microtask queues are determined to be empty and the phase ends.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The close phase is checked again and found empty.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Finally, the timers phase is consulted and callback 5 is executed and prints 5 on the console.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Once that's done, the applications doesn't have any more work to do and it exits.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;As we know, Node.js runtime environment is single-threaded. Running too much code in a single stack will stall the event loop and prevent other callbacks from firing. To prevent this event loop starving situation, you can break your CPU-heavy operations up across multiple stacks. For example, if you are processing 1000 data records, you can consider breaking down into 10 batches of 100 records, using &lt;code&gt;setImmediate()&lt;/code&gt; at the end of each batch to continue processing the next batch. Another option is forking a new child process and offload processing to it. But never break up such work using &lt;code&gt;process.nextTick()&lt;/code&gt;. Doing so will lead to a microtask queue that never empties and your application will be trapped in the same phase forever. The runtime won't throw any error instead it will remain a zombie process that eats through CPU.&lt;/p&gt;

&lt;p&gt;That's all about event loop. &lt;/p&gt;

&lt;p&gt;I hope you have enjoyed reading this article and found it interesting and useful :)&lt;/p&gt;

&lt;p&gt;Thanks and see you later !&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Reference&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Distributed Systems with Node.js (Book)&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>node</category>
      <category>javascript</category>
      <category>webdev</category>
      <category>programming</category>
    </item>
    <item>
      <title>Deep dive into Node.js Architecture</title>
      <dc:creator>Altamash Ali</dc:creator>
      <pubDate>Sat, 06 Nov 2021 08:01:15 +0000</pubDate>
      <link>https://dev.to/altamashali/deep-dive-into-nodejs-architecture-5190</link>
      <guid>https://dev.to/altamashali/deep-dive-into-nodejs-architecture-5190</guid>
      <description>&lt;p&gt;In this article, we are going to deep dive into Node.js architecture and understand the asynchronous nature of Node.js.&lt;/p&gt;

&lt;p&gt;Let's dive into it.&lt;/p&gt;

&lt;p&gt;Node.js is a &lt;strong&gt;single-threaded&lt;/strong&gt;, &lt;strong&gt;asynchronous&lt;/strong&gt;, &lt;strong&gt;event-driven&lt;/strong&gt; runtime environment for running Javascript code on the server.&lt;/p&gt;

&lt;p&gt;By &lt;strong&gt;Single-threaded&lt;/strong&gt; means Javascript runtime executes only one piece of code( or statement) at any instance of time synchronously. It has only one call stack and one heap memory. But then how does runtime handles multiple asynchronous operations in an efficient way ? Node.js handles it efficiently using its event-driven approach. Don't worry about that now. We will come back to it soon :) .&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;I/O(input/output)&lt;/strong&gt; is the slowest among the fundamental operations of a computer. It involves accessing data on the disk, reading and writing a file, waiting for user input, doing a network call, performing some database operation etc. It adds a delay between the moment the request is sent to the device and the moment the operation completes.&lt;/p&gt;

&lt;p&gt;In tradition blocking I/O programming, the function call corresponding to an I/O request will block the execution of the thread until the operation completes. So, any web server that is implemented using blocking I/O will not be able to handle multiple connections in the same thread. Solution to this problem is using a separate thread( or process) to handle each concurrent connection.&lt;/p&gt;

&lt;p&gt;Most modern operating systems support another mechanism to access resources which is called &lt;strong&gt;non-blocking I/O&lt;/strong&gt; where the system call always return immediately without waiting for the I/O operation to complete. To handle concurrent non-blocking resources in an efficient way, it uses a mechanism called &lt;strong&gt;synchronous event demultiplexing&lt;/strong&gt; or &lt;strong&gt;event notification interface&lt;/strong&gt;. The synchronous event demultiplexing watches multiple resources and returns a new event (or set of events) when a read or write operation executed over one of those resources completes. The advantage here is that the synchronous event demultiplexer is synchronous so it blocks until there are new events to process.&lt;/p&gt;

&lt;p&gt;Pseudocode of an algorithm that uses a generic synchronous event demultiplexer to read from two different resources:&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%2Fyn9h9uk7xldj47wr0idn.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%2Fyn9h9uk7xldj47wr0idn.png" alt="Image description"&gt;&lt;/a&gt;&lt;br&gt;
Let's see what is happening in the above code snippet: &lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;The resources are added to a data structure ( in our case watchedList), associating each one with a specific operation ( e.g. read)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The demultiplexer is set up with the group of resources to be watched. The call to demultiplexer.watch() is synchronous and blocks until any of the watched resources are ready for read. When this occurs, the event demultiplexer returns from the call and a new set of events is available to be processed.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Each event returned by the event demultiplexer is processed. At this point, the resource associated with each event is guaranteed to be ready to read and to not block during the operation.  When all the events are processed, the flow will block again on the event demultiplexer until new events are again available to be processed. This is called the mysterious &lt;strong&gt;event loop&lt;/strong&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;You might notice with this pattern that we can handle several I/O operations inside a single thread. Reason we are talking about demultiplexing as using just a single thread, we can deal with multiple resources.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Multithreaded network applications&lt;/strong&gt; handle the network load like this:&lt;/p&gt;

&lt;p&gt;request ---&amp;gt; spawn a thread&lt;br&gt;
               ---&amp;gt; wait for database request&lt;br&gt;
                     ----&amp;gt; answer request&lt;/p&gt;

&lt;p&gt;request ---&amp;gt; spawn a thread&lt;br&gt;
               ---&amp;gt; wait for database request&lt;br&gt;
                     ----&amp;gt; answer request&lt;/p&gt;

&lt;p&gt;request ---&amp;gt; spawn a thread&lt;br&gt;
               ---&amp;gt; wait for database request&lt;br&gt;
                     ----&amp;gt; answer request&lt;/p&gt;

&lt;p&gt;so the thread spend most of their time using 0% CPU waiting for the database to return data. While doing so they have had to allocate memory required for a thread which includes a complete separate program stack for each thread etc. Also they would have to start a thread which while is not as expensive as starting a full process is still not exactly cheap.&lt;/p&gt;

&lt;p&gt;Since, we spend most of our time using 0% CPU, why not run some code when we are not using CPU ? That way, each request will still get the same amount of CPU time as multithreaded applications but we don't need to start a thread. so this is what happens in a single threaded environment:&lt;/p&gt;

&lt;p&gt;request -&amp;gt; make DB req&lt;br&gt;
request -&amp;gt; make DB req&lt;br&gt;
request -&amp;gt; make DB req&lt;br&gt;
DB req complete -&amp;gt; send response&lt;br&gt;
DB req complete -&amp;gt; send response&lt;br&gt;
DB req complete -&amp;gt; send response&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%2F1127vuqm2v7j9lsmlqtf.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%2F1127vuqm2v7j9lsmlqtf.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We can see that using only one thread doesn't impair our ability to run multiple I/O bound tasks concurrently. The tasks are spread over time, instead of being spread across multiple threads.&lt;/p&gt;

&lt;p&gt;Let me now introduce the &lt;strong&gt;reactor pattern&lt;/strong&gt; which is the heart of Node.js. &lt;/p&gt;

&lt;p&gt;The main idea behind the reactor pattern is to have a handler associated with each I/O operation. A handler in Node.js is represented by a callback function.The handler will be invoked as soon as an event is produced and processed by the event loop. So, The reactor pattern handles I/O by blocking until new events are available from a set of observed resources and then reacts by dispatching each event to an associated handler.&lt;/p&gt;

&lt;p&gt;The structure of the reactor pattern is shown 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%2Frse82pit8orgu9p29igg.jpg" 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%2Frse82pit8orgu9p29igg.jpg" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;The application generates a new I/O operation and request will be submitted to Event Demultiplexer. The application also specifies a handler, which will be invoked when the operation completes. Submitting a new request to the Event Demultiplexer is a non-blocking operation and it returns control to the application immediately.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;When a set of I/O operations completes, the Event Demultiplexer pushes a set of corresponding events into the Event Queue.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;After receiving a set of events from Event Demultiplexer, event loop iterates over the items of the Event Queue.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Handler associated with each handler is invoked.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The handler which is part of the application code, gives control back to the Event loop when its execution completes(a).&lt;br&gt;
While the handler execute, it can request new asynchronous operations, which in turn new items are added to the Event Demultiplexer(b).&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;When all the items in the Event Queue are processed, the Event loop blocks again on the Event Demultiplexer, which then triggers another cycle when a new event is available.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;A Node.js application will exit when there are no more pending operations in the event demultiplexer and no more events to be processed inside the event queue.&lt;/p&gt;

&lt;p&gt;Each OS has its own interface for the event demultiplexer and each I/O operation can behave quite differently depending on the type of resource, even within the same OS. &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;To handle these inconsistencies, Node.js core team created a native library called &lt;strong&gt;libuv&lt;/strong&gt; which is written in C++. &lt;/li&gt;
&lt;li&gt;Libuv represents the low-level I/O engine of Node.js. It is a higher-level abstraction for the OS event demultiplexer, which make Node.js compatible with all the major operation systems and normalise the non-blocking behaviour of the different types of resource. &lt;/li&gt;
&lt;li&gt;It also implements the reactor pattern, thus providing an API for creating event loops, managing event queue, running asynchronous I/O operations and queuing other type of tasks.&lt;/li&gt;
&lt;li&gt;Internally libuv maintains a thread pool for managing I/O operations as well as CPU-intensive operations like crypto and zlib. This is a pool of finite size where I/O operations are allowed to happen. If the pool only contains four threads, then only four files can be read at the same time.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The final high level architecture of Nodejs includes:&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%2Fkc8dx6she13uq2f1akyk.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%2Fkc8dx6she13uq2f1akyk.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;A set of bindings responsible for wrapping and exposing libuv and other low level functionalities to Javascript.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;V8, the Javascript engine originally developed by Google for the Chrome browser. This is one of the reason why Node.js is so fast and efficient.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;A core Javascript Library that implements the high-level Node.js API.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Conclusion&lt;/strong&gt;&lt;br&gt;
Node.js architecture is one of the hot topic for backend interviews. Having a deep understanding of Node.js asynchronous nature is a must for all Node.js devs for writing code efficiently. I really hope you have enjoyed reading this article. I would really recommend Node.js Design patterns book if you want to learn more about Node.js. In the &lt;a href="https://dev.to/altamashali/nodejs-event-loop-in-action-d5o"&gt;next article&lt;/a&gt;, we will talk more about event loop. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;References:&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Node.js Design Patterns by Mario Casciaro and Luciano Mammino&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://stackoverflow.com/questions/34855352/how-in-general-does-node-js-handle-10-000-concurrent-requests" rel="noopener noreferrer"&gt;Stack-overflow definitely&lt;/a&gt; :) &lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;See you guys. Bye :)&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>node</category>
      <category>architecture</category>
      <category>webdev</category>
    </item>
  </channel>
</rss>
