<?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: Endalkachew Biruk</title>
    <description>The latest articles on DEV Community by Endalkachew Biruk (@endalk200).</description>
    <link>https://dev.to/endalk200</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%2F537530%2F2ff01f86-064b-4cc2-a06c-7d74a9a1dd92.png</url>
      <title>DEV Community: Endalkachew Biruk</title>
      <link>https://dev.to/endalk200</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/endalk200"/>
    <language>en</language>
    <item>
      <title>JavaScript Promises and Async Await</title>
      <dc:creator>Endalkachew Biruk</dc:creator>
      <pubDate>Sat, 16 Jul 2022 14:42:27 +0000</pubDate>
      <link>https://dev.to/endalk200/javascript-promises-and-async-await-192m</link>
      <guid>https://dev.to/endalk200/javascript-promises-and-async-await-192m</guid>
      <description>&lt;p&gt;In the previous article we have seen what JavaScript callbacks are and what potential issues they have. In this article&lt;br&gt;
we are going to explore JavaScript Promises. How they work, potential issues with promises and, how async and await solves these issues. If you haven't read the previous article I recommend you do. &lt;a href="https://dev.to/endalk200/javascript-callbacks-4fn8"&gt;JavaScript Callbacks Article&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;
  
  
  &lt;strong&gt;Promises&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Have you ever been to a busy restaurant without a reservation? When this happens, the restaurant needs a way to get back in&lt;br&gt;
contact with you when a table opens up. Historically, they'd just take your name and yell it when your table was ready. Then,&lt;br&gt;
as naturally occurs, they decided to start getting fancy. One solution was, instead of taking your name, they'd take your&lt;br&gt;
number and text you once a table opened up. This allowed you to be out of yelling range but more importantly, it allowed them&lt;br&gt;
to target your phone with ads whenever they wanted. Sound familiar? It should! OK, maybe it shouldn't. It's a metaphor for&lt;br&gt;
callbacks! &lt;strong&gt;Giving your number to a restaurant is just like giving a callback function to a third party service. You &lt;em&gt;expect&lt;/em&gt; the restaurant to text you when a table opens up, just like you &lt;em&gt;expect&lt;/em&gt; the third party service to invoke your function when and how they said they would.&lt;/strong&gt; &lt;br&gt;
Once your number or callback function is in their hands though, you've lost all control.&lt;/p&gt;

&lt;p&gt;Thankfully, there is another solution that exists. One that, by design, allows you to keep all the control. You've&lt;br&gt;
probably even experienced it before - it's that little buzzer thing they give you. You know, this one.&lt;/p&gt;

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

&lt;p&gt;If you've never used one before, the idea is simple. Instead of taking your name or number, they give you this&lt;br&gt;
device. When the device starts buzzing and glowing, your table is ready. You can still do whatever you'd like as&lt;br&gt;
you're waiting for your table to open up, but now you don't have to give up anything. In fact, it's the&lt;br&gt;
exact opposite. &lt;strong&gt;They&lt;/strong&gt; have to give &lt;strong&gt;you&lt;/strong&gt; something. There is no inversion of control.&lt;/p&gt;

&lt;p&gt;The buzzer will always be in one of three different states - &lt;strong&gt;&lt;code&gt;pending&lt;/code&gt;&lt;/strong&gt;, &lt;strong&gt;&lt;code&gt;fulfilled&lt;/code&gt;&lt;/strong&gt;, or &lt;strong&gt;&lt;code&gt;rejected&lt;/code&gt;&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;code&gt;pending&lt;/code&gt;&lt;/strong&gt; is the default, initial state. When they give you the buzzer, it's in this state.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;code&gt;fulfilled&lt;/code&gt;&lt;/strong&gt; is the state the buzzer is in when it's flashing and your table is ready.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;code&gt;rejected&lt;/code&gt;&lt;/strong&gt; is the state the buzzer is in when something goes wrong. Maybe the restaurant is about to&lt;br&gt;
close or they forgot someone rented out the restaurant for the night.&lt;/p&gt;

&lt;p&gt;Again, the important thing to remember is that you, the receiver of the buzzer, have all the control. If the&lt;br&gt;
buzzer gets put into &lt;strong&gt;&lt;code&gt;fulfilled&lt;/code&gt;&lt;/strong&gt;, you can go to your table. If it gets put into &lt;strong&gt;&lt;code&gt;fulfilled&lt;/code&gt;&lt;/strong&gt; and you&lt;br&gt;
want to ignore it, cool, you can do that too. If it gets put into &lt;strong&gt;&lt;code&gt;rejected&lt;/code&gt;&lt;/strong&gt;, that sucks but you can go&lt;br&gt;
somewhere else to eat. If nothing ever happens and it stays in &lt;strong&gt;&lt;code&gt;pending&lt;/code&gt;&lt;/strong&gt;, you never get to eat but you're&lt;br&gt;
not actually out anything.&lt;/p&gt;

&lt;p&gt;Now that you're a master of the restaurant buzzer thingy, let's apply that knowledge to something that matters.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;If giving the restaurant your number is like giving them a callback function, receiving the little buzzy thing is like receiving what's called a "Promise".&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;As always, let's start with &lt;strong&gt;why&lt;/strong&gt;. Why do Promises exist? They exist to make the complexity of making&lt;br&gt;
asynchronous requests more manageable. Exactly like the buzzer, a &lt;strong&gt;&lt;code&gt;Promise&lt;/code&gt;&lt;/strong&gt; can be in one of three&lt;br&gt;
states, &lt;strong&gt;&lt;code&gt;pending&lt;/code&gt;&lt;/strong&gt;, &lt;strong&gt;&lt;code&gt;fulfilled&lt;/code&gt;&lt;/strong&gt; or &lt;strong&gt;&lt;code&gt;rejected&lt;/code&gt;&lt;/strong&gt;. Unlike the buzzer, instead of these states representing&lt;br&gt;
the status of a table at a restaurant, they represent the status of an asynchronous request.&lt;/p&gt;

&lt;p&gt;If the async request is still ongoing, the &lt;strong&gt;&lt;code&gt;Promise&lt;/code&gt;&lt;/strong&gt; will have a status of &lt;strong&gt;&lt;code&gt;pending&lt;/code&gt;&lt;/strong&gt;. If the async request&lt;br&gt;
was successfully completed, the &lt;strong&gt;&lt;code&gt;Promise&lt;/code&gt;&lt;/strong&gt; will change to a status of &lt;strong&gt;&lt;code&gt;fulfilled&lt;/code&gt;&lt;/strong&gt;. If the async request&lt;br&gt;
failed, the &lt;strong&gt;&lt;code&gt;Promise&lt;/code&gt;&lt;/strong&gt; will change to a status of &lt;strong&gt;&lt;code&gt;rejected&lt;/code&gt;&lt;/strong&gt;. The buzzer metaphor is pretty spot on, right?&lt;/p&gt;

&lt;p&gt;Now that you understand why Promises exist and the different states they can be in, there are three more questions&lt;br&gt;
we need to answer.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;How do you create a Promise?&lt;/li&gt;
&lt;li&gt;How do you change the status of a promise?&lt;/li&gt;
&lt;li&gt;How do you listen for when the status of a promise changes?&lt;/li&gt;
&lt;/ol&gt;
&lt;h3&gt;
  
  
  &lt;strong&gt;1) How do you create a Promise?&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;This one is pretty straight forward. You create a &lt;strong&gt;&lt;code&gt;new&lt;/code&gt;&lt;/strong&gt; instance of &lt;strong&gt;&lt;code&gt;Promise&lt;/code&gt;&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="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="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Promise&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  &lt;strong&gt;2) How do you change the status of a promise?&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;The &lt;strong&gt;&lt;code&gt;Promise&lt;/code&gt;&lt;/strong&gt; constructor function takes in a single argument, a (callback) function. This function is going&lt;br&gt;
to be passed two arguments, &lt;strong&gt;&lt;code&gt;resolve&lt;/code&gt;&lt;/strong&gt; and &lt;strong&gt;&lt;code&gt;reject&lt;/code&gt;&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;code&gt;resolve&lt;/code&gt;&lt;/strong&gt; - a function that allows you to change the status of the promise to &lt;strong&gt;&lt;code&gt;fulfilled&lt;/code&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;code&gt;reject&lt;/code&gt;&lt;/strong&gt; - a function that allows you to change the status of the promise to &lt;strong&gt;&lt;code&gt;rejected&lt;/code&gt;&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;In the code below, we use &lt;strong&gt;&lt;code&gt;setTimeout&lt;/code&gt;&lt;/strong&gt; to wait 2 seconds and then invoke &lt;strong&gt;&lt;code&gt;resolve&lt;/code&gt;&lt;/strong&gt;. This will change the&lt;br&gt;
status of the promise to &lt;strong&gt;&lt;code&gt;fulfilled&lt;/code&gt;&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="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="k"&gt;new&lt;/span&gt; &lt;span class="nc"&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="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="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="nf"&gt;resolve&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="c1"&gt;// Change status to 'fulfilled'&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="p"&gt;})&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We can see this change in action by logging the promise right after we create it and then again roughly&lt;br&gt;
2 seconds later after &lt;strong&gt;&lt;code&gt;resolve&lt;/code&gt;&lt;/strong&gt; has been called.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fmeij6hnsn7qb5dl3litd.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fmeij6hnsn7qb5dl3litd.gif" alt="resolve gif" width="1144" height="722"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Notice the promise goes from &lt;strong&gt;&lt;code&gt;&amp;lt;pending&amp;gt;&lt;/code&gt;&lt;/strong&gt; to &lt;strong&gt;&lt;code&gt;&amp;lt;resolved&amp;gt;&lt;/code&gt;&lt;/strong&gt;.&lt;/p&gt;
&lt;h3&gt;
  
  
  &lt;strong&gt;3) How do you listen for when the status of a promise changes?&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;In my opinion, this is the most important question. It's cool we know how to create a promise and change its&lt;br&gt;
status, but that's worthless if we don't know how to do anything after the status changes.&lt;/p&gt;

&lt;p&gt;One thing we haven't talked about yet is what a promise actually is. When you create a &lt;strong&gt;&lt;code&gt;new Promise&lt;/code&gt;&lt;/strong&gt;, you're&lt;br&gt;
really just creating a plain old JavaScript object. This object can invoke two methods, &lt;strong&gt;&lt;code&gt;then&lt;/code&gt;&lt;/strong&gt;, and &lt;strong&gt;&lt;code&gt;catch&lt;/code&gt;&lt;/strong&gt;.&lt;br&gt;
Here's the key. When the status of the promise changes to &lt;strong&gt;&lt;code&gt;fulfilled&lt;/code&gt;&lt;/strong&gt;, the function that was passed to &lt;strong&gt;&lt;code&gt;.then&lt;/code&gt;&lt;/strong&gt; will&lt;br&gt;
get invoked. When the status of a promise changes to &lt;strong&gt;&lt;code&gt;rejected&lt;/code&gt;&lt;/strong&gt;, the function that was passed to &lt;strong&gt;&lt;code&gt;.catch&lt;/code&gt;&lt;/strong&gt; will be&lt;br&gt;
invoked. What this means is that once you create a promise, you'll pass the function you want to run if the async request&lt;br&gt;
is successful to &lt;strong&gt;&lt;code&gt;.then&lt;/code&gt;&lt;/strong&gt;. You'll pass the function you want to run if the async request fails to &lt;strong&gt;&lt;code&gt;.catch&lt;/code&gt;&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Let's take a look at an example. We'll use &lt;strong&gt;&lt;code&gt;setTimeout&lt;/code&gt;&lt;/strong&gt; again to change the status of the promise to &lt;strong&gt;&lt;code&gt;fulfilled&lt;/code&gt;&lt;/strong&gt; after&lt;br&gt;
two seconds (2000 milliseconds).&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;onSuccess&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;Success!&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;onError&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;💩&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;promise&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;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="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="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="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="mi"&gt;2000&lt;/span&gt;&lt;span class="p"&gt;)&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="nf"&gt;then&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;onSuccess&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="k"&gt;catch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;onError&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you run the code above you'll notice that roughly 2 seconds later, you'll see "Success!" in the console. Again&lt;br&gt;
the reason this happens is because of two things. First, when we created the promise, we invoked &lt;strong&gt;&lt;code&gt;resolve&lt;/code&gt;&lt;/strong&gt; after&lt;br&gt;
~2000 milliseconds - this changed the status of the promise to &lt;strong&gt;&lt;code&gt;fulfilled&lt;/code&gt;&lt;/strong&gt;. Second, we passed the &lt;strong&gt;&lt;code&gt;onSuccess&lt;/code&gt;&lt;/strong&gt; function&lt;br&gt;
to the promises' &lt;strong&gt;&lt;code&gt;.then&lt;/code&gt;&lt;/strong&gt; method. By doing that we told the promise to invoke &lt;strong&gt;&lt;code&gt;onSuccess&lt;/code&gt;&lt;/strong&gt; when the status of the&lt;br&gt;
promise changed to &lt;strong&gt;&lt;code&gt;fulfilled&lt;/code&gt;&lt;/strong&gt; which it did after ~2000 milliseconds.&lt;/p&gt;

&lt;p&gt;Now let's pretend something bad happened and we wanted to change the status of the promise to &lt;strong&gt;&lt;code&gt;rejected&lt;/code&gt;&lt;/strong&gt;.&lt;br&gt;
Instead of calling &lt;strong&gt;&lt;code&gt;resolve&lt;/code&gt;&lt;/strong&gt;, we would call &lt;strong&gt;&lt;code&gt;reject&lt;/code&gt;&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="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;onSuccess&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;Success!&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;onError&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;💩&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;promise&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;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="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="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="nf"&gt;reject&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="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="nf"&gt;then&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;onSuccess&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="k"&gt;catch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;onError&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now this time instead of the &lt;strong&gt;&lt;code&gt;onSuccess&lt;/code&gt;&lt;/strong&gt; function being invoked, the &lt;strong&gt;&lt;code&gt;onError&lt;/code&gt;&lt;/strong&gt; function will be invoked since we called &lt;strong&gt;&lt;code&gt;reject&lt;/code&gt;&lt;/strong&gt;.&lt;/p&gt;




&lt;p&gt;Now that you know your way around the Promise API, let's start looking at some real code.&lt;/p&gt;

&lt;p&gt;Remember the last async callback example we saw earlier?&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;getUser&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;onSuccess&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;onFailure&lt;/span&gt;&lt;span class="p"&gt;)&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="nf"&gt;getJSON&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
        &lt;span class="na"&gt;url&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;`https://api.github.com/users/&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;success&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;onSuccess&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;error&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;onFailure&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="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;getWeather&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;onSuccess&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;onFailure&lt;/span&gt;&lt;span class="p"&gt;)&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="nf"&gt;getJSON&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
        &lt;span class="na"&gt;url&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;getLocationURL&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;location&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;split&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;,&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)),&lt;/span&gt;
        &lt;span class="na"&gt;success&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;onSuccess&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;error&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;onFailure&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="nf"&gt;$&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;#btn&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;on&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;click&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="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nf"&gt;getUser&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;endalk200&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;user&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="nf"&gt;getWeather&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
                &lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;weather&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="nf"&gt;updateUI&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;weather&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;weather&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;results&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt;
                &lt;span class="p"&gt;},&lt;/span&gt;
                &lt;span class="nx"&gt;showError&lt;/span&gt;
            &lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="p"&gt;},&lt;/span&gt;
        &lt;span class="nx"&gt;showError&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;Is there any way we could use the Promise API here instead of using callbacks? What if we wrap our AJAX&lt;br&gt;
requests inside of a promise? Then we can simply &lt;strong&gt;&lt;code&gt;resolve&lt;/code&gt;&lt;/strong&gt; or &lt;strong&gt;&lt;code&gt;reject&lt;/code&gt;&lt;/strong&gt; depending on how the request goes.&lt;br&gt;
Let's start with &lt;strong&gt;&lt;code&gt;getUser&lt;/code&gt;&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="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;getUser&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="k"&gt;new&lt;/span&gt; &lt;span class="nc"&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="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="p"&gt;{&lt;/span&gt;
        &lt;span class="nx"&gt;$&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getJSON&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
            &lt;span class="na"&gt;url&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;`https://api.github.com/users/&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="na"&gt;success&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="na"&gt;error&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="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;Nice. Notice that the parameters of &lt;strong&gt;&lt;code&gt;getUser&lt;/code&gt;&lt;/strong&gt; have changed. Instead of receiving &lt;strong&gt;&lt;code&gt;id&lt;/code&gt;&lt;/strong&gt;, &lt;strong&gt;&lt;code&gt;onSuccess&lt;/code&gt;&lt;/strong&gt;, a&lt;br&gt;
nd &lt;strong&gt;&lt;code&gt;onFailure&lt;/code&gt;&lt;/strong&gt;, it just receives &lt;strong&gt;&lt;code&gt;id&lt;/code&gt;&lt;/strong&gt;. There's no more need for those other two callback functions because we're no&lt;br&gt;
longer inverting control. Instead, we use the Promise's &lt;strong&gt;&lt;code&gt;resolve&lt;/code&gt;&lt;/strong&gt; and &lt;strong&gt;&lt;code&gt;reject&lt;/code&gt;&lt;/strong&gt; functions. &lt;strong&gt;&lt;code&gt;resolve&lt;/code&gt;&lt;/strong&gt; will be invoked&lt;br&gt;
if the request was successful, &lt;strong&gt;&lt;code&gt;reject&lt;/code&gt;&lt;/strong&gt; will be invoked if there was an error.&lt;/p&gt;

&lt;p&gt;Next, let's refactor &lt;strong&gt;&lt;code&gt;getWeather&lt;/code&gt;&lt;/strong&gt;. We'll follow the same strategy here. Instead of taking in &lt;strong&gt;&lt;code&gt;onSuccess&lt;/code&gt;&lt;/strong&gt; and &lt;strong&gt;&lt;code&gt;onFailure&lt;/code&gt;&lt;/strong&gt; callback&lt;br&gt;
functions, we'll use &lt;strong&gt;&lt;code&gt;resolve&lt;/code&gt;&lt;/strong&gt; and &lt;strong&gt;&lt;code&gt;reject&lt;/code&gt;&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="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;getWeather&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;user&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="k"&gt;new&lt;/span&gt; &lt;span class="nc"&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="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="p"&gt;{&lt;/span&gt;
        &lt;span class="nx"&gt;$&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getJSON&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
            &lt;span class="na"&gt;url&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;getLocationURL&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;location&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;split&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;,&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)),&lt;/span&gt;
            &lt;span class="na"&gt;success&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="na"&gt;error&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="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;Looking good. Now the last thing we need to update is our click handler. Remember, here's the flow we want to take.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Get the user's information from the Github API.&lt;/li&gt;
&lt;li&gt;Use the user's location to get their weather from the Yahoo Weather API.&lt;/li&gt;
&lt;li&gt;Update the UI with the user's info and their weather.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Let's start with #1 - getting the user's information from the Github API.&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;$&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;#btn&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;on&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;click&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="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;userPromise&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;getUser&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;endalk200&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="nx"&gt;userPromise&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;user&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;userPromise&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;showError&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;Notice that now instead of &lt;strong&gt;&lt;code&gt;getUser&lt;/code&gt;&lt;/strong&gt; taking in two callback functions, it returns us a promise that we can call &lt;strong&gt;&lt;code&gt;.then&lt;/code&gt;&lt;/strong&gt; and &lt;strong&gt;&lt;code&gt;.catch&lt;/code&gt;&lt;/strong&gt; on.&lt;br&gt;
If &lt;strong&gt;&lt;code&gt;.then&lt;/code&gt;&lt;/strong&gt; is called, it'll be called with the user's information. If &lt;strong&gt;&lt;code&gt;.catch&lt;/code&gt;&lt;/strong&gt; is called, it'll be called with the error.&lt;/p&gt;

&lt;p&gt;Next, let's do #2 - Use the user's location to get their weather.&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;$&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;#btn&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;on&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;click&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="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;userPromise&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;getUser&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;endalk200&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="nx"&gt;userPromise&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;user&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;weatherPromise&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;getWeather&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="nx"&gt;weatherPromise&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;weather&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;weatherPromise&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;showError&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;})&lt;/span&gt;
    &lt;span class="nx"&gt;userPromise&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;showError&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;Notice we follow the exact same pattern we did in #1 but now we invoke &lt;strong&gt;&lt;code&gt;getWeather&lt;/code&gt;&lt;/strong&gt; passing it the &lt;strong&gt;&lt;code&gt;user&lt;/code&gt;&lt;/strong&gt; object we&lt;br&gt;
got from &lt;strong&gt;&lt;code&gt;userPromise&lt;/code&gt;&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Finally, #3 - Update the UI with the user's info and their weather.&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;$&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;#btn&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;on&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;click&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="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;userPromise&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;getUser&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;endalk200&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="nx"&gt;userPromise&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;user&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;weatherPromise&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;getWeather&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="nx"&gt;weatherPromise&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;weather&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="nf"&gt;updateUI&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;weather&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;weather&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;results&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt;
        &lt;span class="p"&gt;})&lt;/span&gt;
        &lt;span class="nx"&gt;weatherPromise&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;showError&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;})&lt;/span&gt;
    &lt;span class="nx"&gt;userPromise&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;showError&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;Our new code is &lt;em&gt;better&lt;/em&gt;, but there are still some improvements we can make. Before we can make those improvements though, there are two&lt;br&gt;
more features of promises you need to be aware of, chaining and passing arguments from &lt;strong&gt;&lt;code&gt;resolve&lt;/code&gt;&lt;/strong&gt; to &lt;strong&gt;&lt;code&gt;then&lt;/code&gt;&lt;/strong&gt;.&lt;/p&gt;
&lt;h3&gt;
  
  
  &lt;strong&gt;Chaining&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Both &lt;strong&gt;&lt;code&gt;.then&lt;/code&gt;&lt;/strong&gt; and &lt;strong&gt;&lt;code&gt;.catch&lt;/code&gt;&lt;/strong&gt; will return a new promise. That seems like a small detail but it's important because&lt;br&gt;
it means that promises can be chained.&lt;/p&gt;

&lt;p&gt;In the example below, we call &lt;strong&gt;&lt;code&gt;getPromise&lt;/code&gt;&lt;/strong&gt; which returns us a promise that will resolve in at least 2000 milliseconds.&lt;br&gt;
From there, because &lt;strong&gt;&lt;code&gt;.then&lt;/code&gt;&lt;/strong&gt; will return a promise, we can continue to chain our &lt;strong&gt;&lt;code&gt;.then&lt;/code&gt;&lt;/strong&gt;s together until we&lt;br&gt;
throw a &lt;strong&gt;&lt;code&gt;new Error&lt;/code&gt;&lt;/strong&gt; which is caught by the &lt;strong&gt;&lt;code&gt;.catch&lt;/code&gt;&lt;/strong&gt; method.&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;getPromise&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="k"&gt;new&lt;/span&gt; &lt;span class="nc"&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="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nf"&gt;setTimeout&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;resolve&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="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;logA&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;A&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;logB&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;B&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;logCAndThrow&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;C&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Error&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;catchError&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;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="nf"&gt;getPromise&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="nx"&gt;logA&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// A&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;logB&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;// B&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;logCAndThrow&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;// C&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;catchError&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// Error!&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Cool, but why is this so important? Remember back in the callback section we talked about one of the downfalls of callbacks&lt;br&gt;
being that they force you out of your natural, sequential way of thinking. When you chain promises together, it doesn't force&lt;br&gt;
you out of that natural way of thinking because chained promises are sequential. &lt;strong&gt;&lt;code&gt;getPromise runs then logA runs then logB runs then...&lt;/code&gt;&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Just so you can see one more example, here's a common use case when you use the &lt;strong&gt;&lt;code&gt;fetch&lt;/code&gt;&lt;/strong&gt; API. &lt;strong&gt;&lt;code&gt;fetch&lt;/code&gt;&lt;/strong&gt; will return you&lt;br&gt;
a promise that will resolve with the HTTP response. To get the actual JSON, you'll need to call &lt;strong&gt;&lt;code&gt;.json&lt;/code&gt;&lt;/strong&gt;. Because of chaining,&lt;br&gt;
we can think about this in a sequential manner.&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;fetch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;/api/user.json&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="nf"&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="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;json&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="nx"&gt;user&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;// user is now ready to go.&lt;/span&gt;
    &lt;span class="p"&gt;})&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now that we know about chaining, let's refactor our &lt;strong&gt;&lt;code&gt;getUser&lt;/code&gt;&lt;/strong&gt;/&lt;strong&gt;&lt;code&gt;getWeather&lt;/code&gt;&lt;/strong&gt; code from earlier to use 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="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;getUser&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="k"&gt;new&lt;/span&gt; &lt;span class="nc"&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="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="p"&gt;{&lt;/span&gt;
        &lt;span class="nx"&gt;$&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getJSON&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
            &lt;span class="na"&gt;url&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;`https://api.github.com/users/&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="na"&gt;success&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="na"&gt;error&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="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;getWeather&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;user&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="k"&gt;new&lt;/span&gt; &lt;span class="nc"&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="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="p"&gt;{&lt;/span&gt;
        &lt;span class="nx"&gt;$&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getJSON&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
            &lt;span class="na"&gt;url&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;getLocationURL&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;location&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;split&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;,&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)),&lt;/span&gt;
            &lt;span class="na"&gt;success&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="na"&gt;error&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="p"&gt;})&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nf"&gt;$&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;#btn&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;on&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;click&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="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nf"&gt;getUser&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;endalk200&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="nf"&gt;then&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;getWeather&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="nx"&gt;weather&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;// We need both the user and the weather here.&lt;/span&gt;
            &lt;span class="c1"&gt;// Right now we just have the weather&lt;/span&gt;
            &lt;span class="nf"&gt;updateUI&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="c1"&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;catch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;showError&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;It &lt;em&gt;looks&lt;/em&gt; much better, but now we're running into an issue. Can you spot it? In the second &lt;strong&gt;&lt;code&gt;.then&lt;/code&gt;&lt;/strong&gt; we want to call &lt;strong&gt;&lt;code&gt;updateUI&lt;/code&gt;&lt;/strong&gt;.&lt;br&gt;
The problem is we need to pass &lt;strong&gt;&lt;code&gt;updateUI&lt;/code&gt;&lt;/strong&gt; both the &lt;strong&gt;&lt;code&gt;user&lt;/code&gt;&lt;/strong&gt; and the &lt;strong&gt;&lt;code&gt;weather&lt;/code&gt;&lt;/strong&gt;. Currently, how we have it set up,&lt;br&gt;
we're only receiving the &lt;strong&gt;&lt;code&gt;weather&lt;/code&gt;&lt;/strong&gt;, not the &lt;strong&gt;&lt;code&gt;user&lt;/code&gt;&lt;/strong&gt;. Somehow we need to figure out a way to make it so the promise&lt;br&gt;
that &lt;strong&gt;&lt;code&gt;getWeather&lt;/code&gt;&lt;/strong&gt; returns is resolved with both the &lt;strong&gt;&lt;code&gt;user&lt;/code&gt;&lt;/strong&gt; and the &lt;strong&gt;&lt;code&gt;weather&lt;/code&gt;&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Here's the key. &lt;strong&gt;&lt;code&gt;resolve&lt;/code&gt;&lt;/strong&gt; is just a function. Any arguments you pass to it will be passed along to the function given to &lt;strong&gt;&lt;code&gt;.then&lt;/code&gt;&lt;/strong&gt;.&lt;br&gt;
What that means is that inside of &lt;strong&gt;&lt;code&gt;getWeather&lt;/code&gt;&lt;/strong&gt;, if we invoke &lt;strong&gt;&lt;code&gt;resolve&lt;/code&gt;&lt;/strong&gt; ourself, we can pass to it &lt;strong&gt;&lt;code&gt;weather&lt;/code&gt;&lt;/strong&gt; and &lt;strong&gt;&lt;code&gt;user&lt;/code&gt;&lt;/strong&gt;.&lt;br&gt;
Then, the second &lt;strong&gt;&lt;code&gt;.then&lt;/code&gt;&lt;/strong&gt; method in our chain will receive both &lt;strong&gt;&lt;code&gt;user&lt;/code&gt;&lt;/strong&gt; and &lt;strong&gt;&lt;code&gt;weather&lt;/code&gt;&lt;/strong&gt; as an argument.&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;getWeather&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;user&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="k"&gt;new&lt;/span&gt; &lt;span class="nc"&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="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="p"&gt;{&lt;/span&gt;
        &lt;span class="nx"&gt;$&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getJSON&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
            &lt;span class="na"&gt;url&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;getLocationURL&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;location&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;split&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;,&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)),&lt;/span&gt;
            &lt;span class="nf"&gt;success&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;weather&lt;/span&gt;&lt;span class="p"&gt;)&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;user&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;weather&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;weather&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;results&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt;
            &lt;span class="p"&gt;},&lt;/span&gt;
            &lt;span class="na"&gt;error&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="p"&gt;})&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nf"&gt;$&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;#btn&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;on&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;click&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="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nf"&gt;getUser&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;endalk200&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="nf"&gt;then&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;getWeather&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="nx"&gt;data&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;// Now, data is an object with a&lt;/span&gt;
            &lt;span class="c1"&gt;// "weather" property and a "user" property.&lt;/span&gt;
            &lt;span class="nf"&gt;updateUI&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;data&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;catch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;showError&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;blockquote&gt;
&lt;p&gt;You can play around with the final code here&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;It's in our click handler where you really see the power of promises shine compared to callbacks.&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="c1"&gt;// Callbacks 🚫&lt;/span&gt;
&lt;span class="nf"&gt;getUser&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;endalk200&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;user&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="nf"&gt;getWeather&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
            &lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;weather&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="nf"&gt;updateUI&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;weather&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;weather&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;results&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt;
            &lt;span class="p"&gt;},&lt;/span&gt;
            &lt;span class="nx"&gt;showError&lt;/span&gt;
        &lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="nx"&gt;showError&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;// Promises ✅&lt;/span&gt;

&lt;span class="nf"&gt;getUser&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;endalk200&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="nf"&gt;then&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;getWeather&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="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;updateUI&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;data&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;showError&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Following that logic feels natural because it's how we're used to thinking, sequentially. &lt;strong&gt;&lt;code&gt;getUser then getWeather then update the UI with the data&lt;/code&gt;&lt;/strong&gt;.&lt;/p&gt;




&lt;p&gt;Now it's clear that promises drastically increase the readability of our asynchronous code, but is there a way&lt;br&gt;
we can make it even better? Assume that you were on the TC39 committee and you had all the power to add new features to the&lt;br&gt;
JavaScript language. What steps, if any, would you take to improve 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="nf"&gt;$&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;#btn&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;on&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;click&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="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nf"&gt;getUser&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;endalk200&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="nf"&gt;then&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;getWeather&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="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;updateUI&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;data&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;showError&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;As we've discussed, the code reads pretty nicely. Just as our brains work, it's in a sequential order. One issue that we did run&lt;br&gt;
into was that we needed to thread the data (&lt;strong&gt;&lt;code&gt;users&lt;/code&gt;&lt;/strong&gt;) from the first async request all the way through to the last &lt;strong&gt;&lt;code&gt;.then&lt;/code&gt;&lt;/strong&gt;.&lt;br&gt;
This wasn't a big deal, but it made us change up our &lt;strong&gt;&lt;code&gt;getWeather&lt;/code&gt;&lt;/strong&gt; function to also pass along &lt;strong&gt;&lt;code&gt;users&lt;/code&gt;&lt;/strong&gt;. What if we just&lt;br&gt;
wrote our asynchronous code the same way which we write our synchronous code? If we did, that problem would go away entirely and it&lt;br&gt;
would still read sequentially. Here's an idea.&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;$&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;#btn&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;on&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;click&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="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;user&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;getUser&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;endalk200&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;weather&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;getWeather&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="nf"&gt;updateUI&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;weather&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;Well, that would be nice. Our asynchronous code looks exactly like our synchronous code. There's no extra steps our brain needs&lt;br&gt;
to take because we're already very familiar with this way of thinking. Sadly, this obviously won't work. As you know, if we&lt;br&gt;
were to run the code above, &lt;strong&gt;&lt;code&gt;user&lt;/code&gt;&lt;/strong&gt; and &lt;strong&gt;&lt;code&gt;weather&lt;/code&gt;&lt;/strong&gt; would both just be promises since that's what &lt;strong&gt;&lt;code&gt;getUser&lt;/code&gt;&lt;/strong&gt; and &lt;strong&gt;&lt;code&gt;getWeather&lt;/code&gt;&lt;/strong&gt;&lt;br&gt;
return. But remember, we're on TC39. We have all the power to add any feature to the language we want. As is, this code would be really&lt;br&gt;
tricky to make work. We'd have to somehow teach the JavaScript engine to know the difference between asynchronous function invocations&lt;br&gt;
and regular, synchronous function invocations on the fly. Let's add a few keywords to our code to make it easier on the engine.&lt;/p&gt;

&lt;p&gt;First, let's add a keyword to the main function itself. This could clue the engine to the fact that inside of this function, we're&lt;br&gt;
going to have some asynchronous function invocations. Let's use &lt;strong&gt;&lt;code&gt;async&lt;/code&gt;&lt;/strong&gt; for 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="nf"&gt;$&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;#btn&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;on&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;click&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&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;user&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;getUser&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;endalk200&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;weather&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;getWeather&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="nf"&gt;updateUI&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;weather&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;Cool. That seems reasonable. Next let's add another keyword to let the engine know exactly when a function being invoked is&lt;br&gt;
asynchronous and is going to return a promise. Let's use &lt;strong&gt;&lt;code&gt;await&lt;/code&gt;&lt;/strong&gt;. As in, "Hey engine. This function is asynchronous&lt;br&gt;
and returns a promise. Instead of continuing on like you typically do, go ahead and 'await' the eventual value of the&lt;br&gt;
promise and return it before continuing". With both of our new &lt;strong&gt;&lt;code&gt;async&lt;/code&gt;&lt;/strong&gt; and &lt;strong&gt;&lt;code&gt;await&lt;/code&gt;&lt;/strong&gt; keywords in play, our new code&lt;br&gt;
will look 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="nf"&gt;$&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;#btn&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;on&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;click&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&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;user&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;getUser&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;endalk200&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;weather&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;getWeather&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;location&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="nf"&gt;updateUI&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;weather&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;Pretty slick. We've invented a reasonable way to have our asynchronous code look and behave as if it were synchronous.&lt;br&gt;
Now the next step is to actually convince someone on TC39 that this is a good idea. Lucky for us, as you probably guessed&lt;br&gt;
by now, we don't need to do any convincing because this feature is already part of JavaScript and it's called &lt;strong&gt;&lt;code&gt;Async/Await&lt;/code&gt;&lt;/strong&gt;.&lt;/p&gt;


&lt;h3&gt;
  
  
  &lt;strong&gt;async functions return a promise&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Now that you've seen the benefit of Async/Await, let's discuss some smaller details that are important to know. First, anytime you add &lt;strong&gt;&lt;code&gt;async&lt;/code&gt;&lt;/strong&gt; to a function, that function is going to implicitly return a promise.&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;getPromise&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="nf"&gt;getPromise&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Even though &lt;strong&gt;&lt;code&gt;getPromise&lt;/code&gt;&lt;/strong&gt; is literally empty, it'll still return a promise since it was an &lt;strong&gt;&lt;code&gt;async&lt;/code&gt;&lt;/strong&gt; function.&lt;/p&gt;

&lt;p&gt;If the &lt;strong&gt;&lt;code&gt;async&lt;/code&gt;&lt;/strong&gt; function returns a value, that value will also get wrapped in a promise. That means you'll have&lt;br&gt;
to use &lt;strong&gt;&lt;code&gt;.then&lt;/code&gt;&lt;/strong&gt; to access 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="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;x&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;y&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;x&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;y&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nf"&gt;add&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;3&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;result&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="nx"&gt;result&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;// 5&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h3&gt;
  
  
  &lt;strong&gt;await without async is bad&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;If you try to use the &lt;strong&gt;&lt;code&gt;await&lt;/code&gt;&lt;/strong&gt; keyword inside of a function that isn't &lt;strong&gt;&lt;code&gt;async&lt;/code&gt;&lt;/strong&gt;, you'll get an error.&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;$&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;#btn&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;on&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;click&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="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;user&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;getUser&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;endalk200&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// SyntaxError: await is a reserved word&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;weather&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;getWeather&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;location&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// SyntaxError: await is a reserved word&lt;/span&gt;
    &lt;span class="nf"&gt;updateUI&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;weather&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;Here's how I think about it. When you add &lt;strong&gt;&lt;code&gt;async&lt;/code&gt;&lt;/strong&gt; to a function it does two things. It makes it so the&lt;br&gt;
function itself returns (or wraps what gets returned in) a promise and makes it so you can use &lt;strong&gt;&lt;code&gt;await&lt;/code&gt;&lt;/strong&gt; inside of it.&lt;/p&gt;


&lt;h3&gt;
  
  
  &lt;strong&gt;Error Handling&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;You may have noticed we cheated a little bit. In our original code we had a way to catch any errors using &lt;strong&gt;&lt;code&gt;.catch&lt;/code&gt;&lt;/strong&gt;.&lt;br&gt;
When we switched to Async/Await, we removed that code. With Async/Await, the most common approach is to wrap your code&lt;br&gt;
in a &lt;strong&gt;&lt;code&gt;try/catch&lt;/code&gt;&lt;/strong&gt; block to be able to catch the error.&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;$&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;#btn&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;on&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;click&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&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="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;user&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;getUser&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;endalk200&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;weather&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;getWeather&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;location&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="nf"&gt;updateUI&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;weather&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;e&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nf"&gt;showError&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;e&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That concludes our two part series on JavaScript callbacks and, async and await. If you have questions or feedback I would appreciate it if you leave a comment below.&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>typescript</category>
      <category>webdev</category>
      <category>node</category>
    </item>
    <item>
      <title>Mastering JavaScript Callbacks</title>
      <dc:creator>Endalkachew Biruk</dc:creator>
      <pubDate>Tue, 29 Mar 2022 15:22:27 +0000</pubDate>
      <link>https://dev.to/endalk200/javascript-callbacks-4fn8</link>
      <guid>https://dev.to/endalk200/javascript-callbacks-4fn8</guid>
      <description>&lt;p&gt;Asynchronous processing is one of the most important aspects of the JavaScript language. JavaScript is a single-threaded language, so it needs a mechanism to deal with the actions like performing time-intensive and potentially unreliable activities like making REST API calls, reading files from the disk, or interacting with user input.&lt;/p&gt;

&lt;p&gt;In JavaScript the mechanism used is an &lt;em&gt;event loop&lt;/em&gt;, which processes a callback queue in order from oldest item to newest. Each item in the queue is a message that’s processed completely before moving on to the next message. Each message is a function that returns a response to code elsewhere in the application. Functions used in this way are called callback functions.&lt;/p&gt;

&lt;p&gt;Because of callbacks, JavaScript can use a number of techniques for getting around its single-threaded nature to implement asynchronous processing. In this and the next article we will try to explain these concepts, So buckle up it's gonna be a bumpy ride 😁. &lt;/p&gt;

&lt;p&gt;In this one we are going to see JavaScript callbacks. We are going to explore what they are, why and where we use them. We will also see the potential issues with Callbacks and in the next article we are going to explore what promises are, the issues associated with using them and how async await solves those issues.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Callbacks&lt;/strong&gt;
&lt;/h3&gt;

&lt;blockquote&gt;
&lt;p&gt;I'm going to assume you know exactly 0 about callbacks. If I'm assuming wrong, just scroll down a bit.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;When I was first learning JavaScript, it helped me to think about functions as machines. These machines can do anything you want them to. They can even accept input and return a value. Each machine has a button on it that you can press when you want the machine to run.&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;add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;x&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;y&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;x&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;y&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nf"&gt;add&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;3&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// Press the button, run the machine.&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Whether &lt;strong&gt;I&lt;/strong&gt; press the button, &lt;strong&gt;you&lt;/strong&gt; press the button, or &lt;strong&gt;someone else&lt;/strong&gt; presses the button it doesn't matter. Whenever the button is pressed, like it or not, the machine is going to run.&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;add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;x&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;y&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;x&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;y&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;me&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;add&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;you&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;add&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;someoneElse&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;add&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="nf"&gt;me&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;3&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// Press the button, run the machine.&lt;/span&gt;
&lt;span class="nf"&gt;you&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;3&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// Press the button, run the machine.&lt;/span&gt;
&lt;span class="nf"&gt;someoneElse&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;3&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// Press the button, run the machine.&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In the code above we assign the &lt;strong&gt;&lt;code&gt;add&lt;/code&gt;&lt;/strong&gt; function to three different variables, &lt;strong&gt;&lt;code&gt;me&lt;/code&gt;&lt;/strong&gt;, &lt;strong&gt;&lt;code&gt;you&lt;/code&gt;&lt;/strong&gt;, and &lt;strong&gt;&lt;code&gt;someoneElse&lt;/code&gt;&lt;/strong&gt;. It's important to note that the original &lt;strong&gt;&lt;code&gt;add&lt;/code&gt;&lt;/strong&gt; and each of the variables we created are pointing to the same spot in memory. They're literally the exact same thing under different names. So when we invoke &lt;strong&gt;&lt;code&gt;me&lt;/code&gt;&lt;/strong&gt;, &lt;strong&gt;&lt;code&gt;you&lt;/code&gt;&lt;/strong&gt;, or &lt;strong&gt;&lt;code&gt;someoneElse&lt;/code&gt;&lt;/strong&gt;, it's as if we're invoking &lt;strong&gt;&lt;code&gt;add&lt;/code&gt;&lt;/strong&gt;. Now, what if we take our &lt;strong&gt;&lt;code&gt;add&lt;/code&gt;&lt;/strong&gt; machine and pass it to another machine? Remember, it doesn't matter who presses the () button, if it's pressed, it's going to run.&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;add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;x&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;y&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;x&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;y&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;addFive&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;x&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;addReference&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="nf"&gt;addReference&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;x&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="c1"&gt;// 15 - Press the button, run the machine.&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nf"&gt;addFive&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;add&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// 15&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Your brain might have got a little weird on this one, nothing new is going on here though. Instead of "pressing the button" on &lt;strong&gt;&lt;code&gt;add&lt;/code&gt;&lt;/strong&gt;, we pass &lt;strong&gt;&lt;code&gt;add&lt;/code&gt;&lt;/strong&gt; as an argument to &lt;strong&gt;&lt;code&gt;addFive&lt;/code&gt;&lt;/strong&gt;, rename it &lt;strong&gt;&lt;code&gt;addReference&lt;/code&gt;&lt;/strong&gt;, and then we "press the button" or invoke it.&lt;/p&gt;

&lt;p&gt;This highlights some important concepts of the JavaScript language. First, just as you can pass a string or a number as an argument to a function, so too can you pass a reference to a function as an argument. When you do this the function you're passing as an argument is called a &lt;strong&gt;callback&lt;/strong&gt; function and the function you're passing the callback function to is called a &lt;strong&gt;higher order function&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Because vocabulary is important, here's the same code with the variables re-named to match the concepts they're demonstrating.&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;add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;x&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;y&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;x&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;y&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;higherOrderFunction&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;x&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;callback&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="nf"&gt;callback&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;x&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;span class="nf"&gt;higherOrderFunction&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;add&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This pattern should look familiar, it's everywhere. If you've ever used any of the JavaScript Array methods, you've used a callback. If you've ever used lodash, you've used a callback. If you've ever used jQuery, you've used a callback.&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="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="mi"&gt;2&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="nf"&gt;map&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;i&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;i&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;5&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="nf"&gt;filter&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="mi"&gt;2&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="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;n&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;n&lt;/span&gt; &lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="nf"&gt;$&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;#btn&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;on&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;click&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="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="s2"&gt;Callbacks are everywhere&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;In general, there are two popular use cases for callbacks. The first, and what we see in the &lt;strong&gt;&lt;code&gt;.map&lt;/code&gt;&lt;/strong&gt; and &lt;strong&gt;&lt;code&gt;_.filter&lt;/code&gt;&lt;/strong&gt;&lt;br&gt;
examples, is a nice abstraction over transforming one value into another. We say "Hey, here's an array and a function. Go ahead and get me a new value based on the function I gave you". The second, and what we see in the jQuery example, is delaying execution of a function until a particular time. "Hey, here's this function. Go ahead and invoke it whenever the element with an id of &lt;strong&gt;&lt;code&gt;btn&lt;/code&gt;&lt;/strong&gt; is clicked." It's this second use case that we're going to focus on, "delaying execution of a function until a particular time".&lt;/p&gt;

&lt;p&gt;Right now we've only looked at examples that are synchronous. As we talked about at the beginning of this post, most of the apps we build don't have all the data they need up front. Instead, they need to fetch external data as the user interacts with the app. We've just seen how callbacks can be a great use case&lt;br&gt;
for this because, again, they allow you to "delay execution of a function until a particular time". It doesn't take much imagination to see how we can adapt that sentence to work with data fetching. Instead of delaying execution of a function until &lt;em&gt;a particular time&lt;/em&gt;, we can delay execution of a function &lt;em&gt;until we have the data we need&lt;/em&gt;. Here's probably&lt;br&gt;
the most popular example of this, jQuery's &lt;strong&gt;&lt;code&gt;getJSON&lt;/code&gt;&lt;/strong&gt; method.&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="c1"&gt;// updateUI and showError are irrelevant.&lt;/span&gt;
&lt;span class="c1"&gt;// Pretend they do what they sound like.&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;endalk200&lt;/span&gt;&lt;span class="dl"&gt;"&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="nf"&gt;getJSON&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
    &lt;span class="na"&gt;url&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;`https://api.github.com/users/&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;success&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;updateUI&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;error&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;showError&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We can't update the UI of our app until we have the user's data. So what do we do? We say, "Hey, here's an object. If&lt;br&gt;
the request succeeds, go ahead and call &lt;strong&gt;&lt;code&gt;success&lt;/code&gt;&lt;/strong&gt; passing it the user's data. If it doesn't, go ahead and call &lt;strong&gt;&lt;code&gt;error&lt;/code&gt;&lt;/strong&gt;&lt;br&gt;
passing it the error object. You don't need to worry about what each method does, just be sure to call them when you're&lt;br&gt;
supposed to". This is a perfect demonstration of using a callback for async requests.&lt;/p&gt;



&lt;p&gt;At this point, we've learned about what callbacks are and how they can be beneficial both in synchronous and asynchronous code. What we haven't talked yet is the dark side of callbacks. Take a look at this code below. Can you tell what's happening?&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="c1"&gt;// updateUI, showError, and getLocationURL are irrelevant.&lt;/span&gt;
&lt;span class="c1"&gt;// Pretend they do what they sound like.&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;endalk200&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="nf"&gt;$&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;#btn&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;on&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;click&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="o"&gt;=&amp;gt;&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="nf"&gt;getJSON&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
        &lt;span class="na"&gt;url&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;`https://api.github.com/users/&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;success&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;user&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;$&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getJSON&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
                &lt;span class="na"&gt;url&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;getLocationURL&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;location&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;split&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;,&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)),&lt;/span&gt;
                &lt;span class="nf"&gt;success&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;weather&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                    &lt;span class="nf"&gt;updateUI&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;weather&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;weather&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;results&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;
                &lt;span class="p"&gt;},&lt;/span&gt;
                &lt;span class="na"&gt;error&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;showError&lt;/span&gt;
            &lt;span class="p"&gt;});&lt;/span&gt;
        &lt;span class="p"&gt;},&lt;/span&gt;
        &lt;span class="na"&gt;error&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;showError&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;Notice we've added a few more layers of callbacks. First, we're saying don't run the initial AJAX request until the element with an id of &lt;strong&gt;&lt;code&gt;btn&lt;/code&gt;&lt;/strong&gt; is clicked. Once the button is clicked, we make the first request. If that request succeeds, we make a second request. If that request succeeds, we invoke the &lt;strong&gt;&lt;code&gt;updateUI&lt;/code&gt;&lt;/strong&gt; method passing it the data we got from both requests. Regardless of if you understood the code at first glance or not, objectively it's much harder to read than the code before. This brings us to the topic of "&lt;strong&gt;Callback Hell&lt;/strong&gt;".&lt;/p&gt;

&lt;p&gt;As humans, we naturally think sequentially. When you have nested callbacks inside of nested callbacks, it forces you out of your natural way of thinking. Bugs happen when there's a disconnect between how your software is read and how you naturally think.&lt;/p&gt;

&lt;p&gt;Like most solutions to software problems, a commonly prescribed approach for making "Callback Hell" easier to consume is to modularize your 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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;getUser&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;onSuccess&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;onFailure&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;$&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getJSON&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
        &lt;span class="na"&gt;url&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;`https://api.github.com/users/&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;success&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;onSuccess&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;error&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;onFailure&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;getWeather&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;onSuccess&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;onFailure&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;$&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getJSON&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
        &lt;span class="na"&gt;url&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;getLocationURL&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;location&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;split&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;,&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)),&lt;/span&gt;
        &lt;span class="na"&gt;success&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;onSuccess&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;error&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;onFailure&lt;/span&gt;
    &lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="nf"&gt;$&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;#btn&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;on&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;click&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="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nf"&gt;getUser&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;endalk200&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;user&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="nf"&gt;getWeather&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
                &lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;weather&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="nf"&gt;updateUI&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;weather&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;weather&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;results&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;
                &lt;span class="p"&gt;},&lt;/span&gt;
                &lt;span class="nx"&gt;showError&lt;/span&gt;
            &lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="p"&gt;},&lt;/span&gt;
        &lt;span class="nx"&gt;showError&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;OK, the function names help us understand what's going on, but is it objectively "better"? Not by much. We've put a band-aid over the readability issue of Callback Hell. The problem still exists that we naturally think sequentially and, even with the extra functions, nested callbacks break us out of that sequential way of thinking.&lt;/p&gt;




&lt;p&gt;The next issue of callbacks has to do with &lt;a href="https://en.wikipedia.org/wiki/Inversion_of_control"&gt;inversion of control&lt;/a&gt;. When you write a callback, you're assuming that the program you're giving the callback to is responsible and will call it when (and only when) it's supposed to. You're essentially inverting the control of your program over to another&lt;br&gt;
program. When you're dealing with libraries like jQuery, lodash, or even vanilla JavaScript, it's safe to assume that the callback function will be invoked at the correct time with the correct arguments. However, for many third-party libraries, callback functions are the interface for how you interact with them. It's entirely plausible that a third party library could,&lt;br&gt;
whether on purpose or accidentally, break how they interact with your callback.&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;criticalFunction&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="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// It's critical that this function&lt;/span&gt;
    &lt;span class="c1"&gt;// gets called and with the correct arguments.&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

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

&lt;/div&gt;



&lt;p&gt;Since you're not the one calling &lt;strong&gt;&lt;code&gt;criticalFunction&lt;/code&gt;&lt;/strong&gt;, you have 0 control over when and with what argument it's invoked. &lt;em&gt;Most&lt;/em&gt; of the time this isn't an issue, but when it is, it's a big one.&lt;/p&gt;




&lt;p&gt;In the next article we are going to explore JavaScript promises and how they can provide a potential solution to the&lt;br&gt;
&lt;a href="https://en.wikipedia.org/wiki/Inversion_of_control"&gt;inversion of control&lt;/a&gt; problem.&lt;/p&gt;

&lt;p&gt;You can find the next article on JavaScript promises and, async and await &lt;a href="https://dev.to/endalk200/javascript-promises-and-async-await-192m"&gt;here&lt;/a&gt;&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>callback</category>
      <category>webdev</category>
    </item>
    <item>
      <title>Production-Ready Docker Configuration With DigitalOcean Container Registry Part II</title>
      <dc:creator>Endalkachew Biruk</dc:creator>
      <pubDate>Wed, 03 Nov 2021 11:54:24 +0000</pubDate>
      <link>https://dev.to/endalk200/production-ready-docker-configuration-with-digitalocean-container-registry-part-ii-4e37</link>
      <guid>https://dev.to/endalk200/production-ready-docker-configuration-with-digitalocean-container-registry-part-ii-4e37</guid>
      <description>&lt;p&gt;&lt;strong&gt;Prerequisite-&lt;/strong&gt; If you didn’t read part I of this article I suggest you read that first &lt;a href="https://dev.to/endalk200/production-ready-docker-configuration-with-digitalocean-container-registry-part-i-2bjh"&gt;here&lt;/a&gt;. I am assuming you already have a working DigitalOcean account. If you don’t have an account create an account using &lt;a href="https://m.do.co/c/713dfe72e086"&gt;this&lt;/a&gt; link and get 100 USD free credit.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Objective-&lt;/strong&gt; In part I of this article series we discussed the two dockerfiles powering the web server and our database. We also discussed some configuration files and scripts needed to run and operate our containers. In this article, we are going to build our docker image, push it to DigitalOcean container registry and deploy it to DigitalOcean App platform. We will also setup CI/CD for the build and deploy process using GitHub actions.&lt;/p&gt;

&lt;p&gt;To get full code for this blog clone the repository.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git clone https://github.com/endalk200/prod-django-docker-config.git
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;or download the zip file &lt;a href="https://github.com/endalk200/prod-django-docker-config"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;We will do this step by step.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Step 1- Install and configure &lt;code&gt;doctl&lt;/code&gt;&lt;/strong&gt;
&lt;/h3&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;code&gt;doctl&lt;/code&gt; is CLI for interacting with DigitalOcean APIs. &lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;To install this CLI refer to &lt;a href="https://github.com/digitalocean/doctl#installing-doctl"&gt;this&lt;/a&gt; official documentation. It has instructions for each platform and package managers. After you install the CLI you have to authenticate the CLI to interact with DigitalOcean APIs. To do that you have to generate &lt;code&gt;AuthToken&lt;/code&gt; first. Go to your DigitalOcean dashboard, and click the &lt;strong&gt;API&lt;/strong&gt; then &lt;strong&gt;Generate New Token&lt;/strong&gt; Button&lt;/p&gt;

&lt;p&gt;Give your token a name and generate the token. You will see the token generated in a table (Notice: This token is only visible to you once so copy the token and store it in a secure location). Now that you have you access token lets authenticated the CLI from your terminal run&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;doctl auth init
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;After that, you will be prompted to enter the access token, Paste it there and click enter. After that, you should see a message like this.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Validating token: OK
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now you have installed and configured your CLI to talk to DigitalOcean APIs you are good to go.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 2 — Build and push your image to container registry
&lt;/h3&gt;

&lt;p&gt;Before we build our docker image we need to create container registry on DigitalOcean. Go to the **Container Registry **and you will be prompted with the following.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--aH-zriFf--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn.hashnode.com/res/hashnode/image/upload/v1634470523194/huHbUf5Yf.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--aH-zriFf--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn.hashnode.com/res/hashnode/image/upload/v1634470523194/huHbUf5Yf.png" alt="Digital ocean container registry dashboard" width="800" height="392"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Enter the name (the name should be unique) of the container registry you want to create, chose a plan that suits your needs, and **Create Registry. **After creating your registry you will be redirected to your registry page like this.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--s1Q8g3SL--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn.hashnode.com/res/hashnode/image/upload/v1634470524983/7lAiwjD2O.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--s1Q8g3SL--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn.hashnode.com/res/hashnode/image/upload/v1634470524983/7lAiwjD2O.png" alt="Digital ocean container registry dashboard" width="800" height="294"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Copy the registry URL (we are going to need that URL when we push to this registry).&lt;/p&gt;

&lt;p&gt;By default, docker pulls and pushes Docker images from docker hub. We want docker to point to the container registry we just created. We can do that by running the following command.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;doctl registry login
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This command will tell docker to point to DigitalOcean for container registry.&lt;/p&gt;

&lt;p&gt;To build our docker image run the following command in the root directory of the project.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;docker build -t my-image-name:latest
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In this command, we are tagging our image with the name &lt;code&gt;my-image-name&lt;/code&gt; After that, we are telling Docker to tag the version of this docker image &lt;code&gt;latest&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;The command will build the docker image and store it locally. What we want is to push the image to our container registry. To do that run&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;docker tag my-image-name:latest registry.digitalocean.com/my-registry1r43d/my-image-name:latest
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This command is tagging our docker image we just build and pointing it to the container registry we created above. To push our container use the following command.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;docker push registry.digitalocean.com/my-registry1r43d/my-image-name:latest
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Step 3 —Setup CI/CD for the build process using GitHub actions
&lt;/h3&gt;

&lt;p&gt;Now that we built our Docker image and push it to DigitalOcean container registry let's configure CI/CD for this process.&lt;/p&gt;

&lt;p&gt;Before we setup CI/CD with GitHub we need to create a repository secret in our GitHub repository settings tab. Name the secret CONTAINER_REGISTRY_TOKEN and the value of the token we created above. After that create &lt;code&gt;.github/workflows&lt;/code&gt; directory in you root project and create a file with the name of &lt;code&gt;docker-image-build-push.yml&lt;/code&gt; and put the following yml config in it.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;name: Build and push docker imageon:  

push:    
    branches:      
        - release

jobs:  
    build:    
        runs-on: ubuntu-latest    
        steps:      
            - name: Checkout master        
              uses: actions/checkout@main      
            - name: Install doctl        
              uses: digitalocean/action-doctl@v2        
              with:          
                  token: ${{ secrets.CONTAINER_REGISTRY_TOKEN }}
            - name: Build container image        
              run: docker build -t my-image-name:latest
            - name: Log in to DigitalOcean Container Registry    
              run: doctl registry login --expiry-seconds 1200
            - name: Tag the container being built
              run: docker tag my-image-name:latest registry.digitalocean.com/my-registry1r43d/my-image-name:latest
            - name: Push image to DigitalOcean Container Registry
              run: docker push registry.digitalocean.com/my-registry1r43d/my-image-name:latest
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Step 4 — Deploy your container to app platform
&lt;/h3&gt;

&lt;p&gt;App platform is DigitalOceans PAAS offering. We can deploy to this platform from our terminal using the CLI we installed. First, create yml file with the following config and name it &lt;code&gt;spec.yml&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;name: my-project
services:
- name: my-project-image
  image:
    registry_type: "DOCR"
    registry: "my-registry1r43d"
    repository: "my-image-name"
    tag: "latest"
  run_command: start.sh server --worker-tmp-dir /dev/shm
  envs:
  - key: DEBUG
    scope: RUN_AND_BUILD_TIME
    value: "False"
  http_port: 8080
  instance_count: 1
  instance_size_slug: basic-xs
  routes:
  - path: /
  source_dir: /
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The above config file tells DigitalOcean how to create your instance and run it.&lt;/p&gt;

&lt;p&gt;To create the instance run the following command.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;doctl apps create --spec spec.yml
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;After that command is executed your web app will be live with HTTPS and you can see the process in your dashboard.&lt;/p&gt;

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

&lt;p&gt;This two-part article attempted to cover production level docker configuration and how you can build and deploy the image to DigitalOcean container registry. The deployment process guide is only meant to get you started there are many considerations when deploying your web application.&lt;/p&gt;

&lt;p&gt;To get the full code and try it for yourself, It is on GitHub &lt;a href="https://github.com/endalk200/prod-django-docker-config"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Please comment on any gaps or improvements in the above setup. Follow me for more articles like this one.&lt;/p&gt;

&lt;p&gt;Use the following link and get 100 USD in DigitalOcean free credit.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.digitalocean.com/?refcode=713dfe72e086&amp;amp;utm_campaign=Referral_Invite&amp;amp;utm_medium=Referral_Program&amp;amp;utm_source=badge"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--YS4lrG-m--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://web-platforms.sfo2.digitaloceanspaces.com/WWW/Badge%25203.svg" alt="DigitalOcean Referral Badge" width="200" height="65"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Follow me to get articles like this and more.&lt;/p&gt;

</description>
      <category>django</category>
      <category>docker</category>
      <category>production</category>
      <category>python</category>
    </item>
    <item>
      <title>Production-Ready Docker Configuration With DigitalOcean Container Registry Part I</title>
      <dc:creator>Endalkachew Biruk</dc:creator>
      <pubDate>Wed, 03 Nov 2021 11:53:13 +0000</pubDate>
      <link>https://dev.to/endalk200/production-ready-docker-configuration-with-digitalocean-container-registry-part-i-2bjh</link>
      <guid>https://dev.to/endalk200/production-ready-docker-configuration-with-digitalocean-container-registry-part-i-2bjh</guid>
      <description>&lt;p&gt;&lt;strong&gt;&lt;em&gt;Prerequisites-&lt;/em&gt;&lt;/strong&gt;This article assumes a basic understanding of Docker and Django.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Objective&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;em&gt;Part I of this article series will be setting up a basic Django web app with development level docker configuration using docker-compose and production level docker configuration. We will also discuss in detail the rationale behind our docker configuration.&lt;/em&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://endalk200.medium.com/production-ready-docker-configuration-with-digitalocean-container-registry-part-ii-5361b8e6d5e0" rel="noopener noreferrer"&gt;Part II&lt;/a&gt; we will be building our docker image, push it to DigitalOcean container registry, and setup CI/CD pipeline with GitHub actions. We will also be deploying our built docker image to app platform and setup CI/CD using GitHub actions.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Docker has revolutionized software development and has proven to be the nucleus of new-age development practices like CI-CD, distributed development, and collaboration.&lt;/p&gt;

&lt;p&gt;Still, there isn’t any popular consensus on what are good docker development principles and guidelines. Dockerfiles written for Java or any other programming language don’t directly translate to Python.&lt;/p&gt;

&lt;p&gt;This article discusses an opinionated, production-ready Docker setup for Django applications which can be used in docker-compose files or with Kubernetes clusters. Our requirement further extends for containers to be scaled up and down without any side effects.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Note&lt;/strong&gt;: Even though our docker configuration is production-ready the Django application itself is in no way ready for production.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;em&gt;If you need the code without going into the reasoning, a sample Django repo with Docker setup is available for download on Github, &lt;a href="https://github.com/endalk200/prod-django-docker-config" rel="noopener noreferrer"&gt;here&lt;/a&gt;.&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;So without further ado, let's start. The tech stacks we are using are:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://docs.celeryproject.org/en/stable/index.html" rel="noopener noreferrer"&gt;Celery&lt;/a&gt; is used for background tasks, with Redis as the celery backend.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://docs.celeryproject.org/en/stable/userguide/periodic-tasks.html" rel="noopener noreferrer"&gt;Celery beat&lt;/a&gt; is used for cron jobs, to schedule periodic tasks.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://flower.readthedocs.io/en/latest/" rel="noopener noreferrer"&gt;Flower&lt;/a&gt; is used for background tasks monitoring.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;We are using PostgreSQL as our Database.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Both Django server and celery will be run from one docker image thus they share the same docker configuration. For database backup and restore purposes we are going to use a custom image for our PostgreSQL with maintenance commands and scripts. Thus we have two dockerfiles, one for our Django server and one for PostgreSQL. We will discuss both docker configs in detail below.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Django Docker Configuration&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Let's go over our first dockerfile which runs the web server and celery.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# Section 1- Basic parameters
ARG PYTHON_VERSION=3.9-slim-buster
ARG BUILD_ENVIRONMENT=production
ARG APP_HOME=/app

# Section 2- Set the python base image
FROM python:${PYTHON_VERSION}

# Section 3- Python interpreter flags
ENV PYTHONUNBUFFERED 1
ENV PYTHONDONTWRITEBYTECODE 1

# Section 4- Compiler and OS libraries
RUN apt-get update &amp;amp;&amp;amp; apt-get install --no-install-recommends -y \
    build-essential \
    # psycopg2 dependencies
    libpq-dev \

    # Translations dependencies
    gettext \

    # cleaning up unused files
    &amp;amp;&amp;amp; apt-get purge -y --auto-remove -o \
    APT::AutoRemove::RecommendsImportant=false \
    &amp;amp;&amp;amp; rm -rf /var/lib/apt/lists/

# Section 5- Project libraries and User Creation
COPY requirements.txt /tmp/requirements.txt

RUN pip install --no-cache-dir -r /tmp/requirements.txt \
    &amp;amp;&amp;amp; rm -rf /tmp/requirements.txt \

RUN useradd -U app_user \
    &amp;amp;&amp;amp; install -d -m 0755 -o app_user -g app_user /app/static

# Section 6- Code and User Setup
WORKDIR ${APP_HOME}

USER app_user:app_user

COPY --chown=app_user:app_user . ${APP_HOME}

RUN chmod +x ./*.sh &amp;amp;&amp;amp; chmod +x ./postgresql/maintenance/*.sh &amp;amp;&amp;amp; \
    chmod +x ./postgresql/maintenance/_sourced/*.sh

# Section 7- Docker Run Checks and Configurations
ENTRYPOINT [ "./entrypoint.sh" ]

CMD [ "./start.sh", "server" ]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Let’s explore each section of our Dockerfile:&lt;/p&gt;

&lt;h3&gt;
  
  
  Section 1- Basic Parameters
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# Step 1- Set arguments used throughout the build
ARG PYTHON_VERSION=3.9-slim-buster
ARG BUILD_ENVIRONMENT=production
ARG APP_HOME=/app
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In the first section of our Dockerfile, we are declaring arguments or variables we are going to use throughout the build process. This is good practice for maintenance and updates later on. If you want to update or change one config you don’t need to go through all of your docker configurations.&lt;/p&gt;

&lt;h3&gt;
  
  
  Section 2- Base Image
&lt;/h3&gt;

&lt;p&gt;We have selected &lt;code&gt;python:3.9-slim-buster&lt;/code&gt; as the base image. While choosing a base image key consideration is its size, as a bigger base image results in a bigger docker image size. Developers prefer &lt;code&gt;alpine&lt;/code&gt; flavor due to its small size and for languages such as Java or Scala, in most cases, it is the right way to go. Alpine is a minimal Docker image based on Alpine Linux.&lt;/p&gt;

&lt;p&gt;But for Python applications, many requisite libraries are not supported by &lt;code&gt;alpine&lt;/code&gt; flavor out of the box. It means you would end up downloading dependencies on &lt;code&gt;alpine&lt;/code&gt; flavor which will result in bigger image size. This also means, greater image build time and application incompatibility. The slim flavor sits between &lt;code&gt;alpine&lt;/code&gt; and full version and hits the sweet spot in terms of size and compatibility.&lt;/p&gt;

&lt;p&gt;If you want to dig deep into this topic &lt;a href="https://dev.to/pmutua/the-best-docker-base-image-for-your-python-application-3o83"&gt;this&lt;/a&gt; article can get you started.&lt;/p&gt;

&lt;h3&gt;
  
  
  Section 3- Python Interpreter Flags
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;*# Section 3- Python interpreter flags
*ENV PYTHONUNBUFFERED *1
*ENV PYTHONDONTWRITEBYTECODE *1*
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We have set two flags &lt;code&gt;PYTHONUNBUFFERED&lt;/code&gt; and &lt;code&gt;PYTHONDONTWRITEBYTECODE&lt;/code&gt; to non-empty values to modify the behavior of the Python interpreter.&lt;/p&gt;

&lt;p&gt;When set to a non-empty value, &lt;code&gt;PYTHONUNBUFFERED&lt;/code&gt; will send python output straight to the terminal(standard output) without being buffered. This helps in two ways. Firstly, this allows us to get logs in real-time. Secondly, in case of container crash, it ensures that you receive output and hence, the reason for failure.&lt;/p&gt;

&lt;p&gt;We are also setting &lt;code&gt;PYTHONDONTWRITEBYTECODE&lt;/code&gt; to a non-empty value. This ensures that the Python interpreter doesn’t generate &lt;code&gt;.pyc&lt;/code&gt; files which apart from being useless in our use-case, can also lead to few hard-to-find bugs due to caching.&lt;/p&gt;

&lt;h3&gt;
  
  
  Section 4- Compiler and OS libraries
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# Section 4- Compiler and OS libraries
RUN apt-get update &amp;amp;&amp;amp; apt-get install --no-install-recommends -y \
    build-essential \
    # psycopg2 dependencies
    libpq-dev \

    # Translations dependencies
    gettext \

    # cleaning up unused files
    &amp;amp;&amp;amp; apt-get purge -y --auto-remove -o \
    APT::AutoRemove::RecommendsImportant=false \
    &amp;amp;&amp;amp; rm -rf /var/lib/apt/lists/
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Commands in this section install compilers, tools, and OS-level libraries. For e.g. &lt;code&gt;apt-get update&lt;/code&gt; , as you may already know, update the list of available packages. It doesn’t update packages themselves, just fetches their latest versions.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;apt-get install -y --no-install-recommends build-essential \
libpq-dev gettext
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;build-essential&lt;/code&gt; contains a collection of meta-packages that are necessary to compile software. This includes, but is not limited to, GNU debugger, g++/GNU compiler collection, and a few other tools and libraries. The complete list of &lt;code&gt;build-essential&lt;/code&gt; packages can be found &lt;a href="https://packages.ubuntu.com/focal/build-essential" rel="noopener noreferrer"&gt;here&lt;/a&gt;. As per official documentation &lt;code&gt;libpq-dev&lt;/code&gt; contains,&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Header files and static library for compiling C programs to link with the libpq library in order to communicate with a PostgreSQL database backend.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Since &lt;code&gt;libpq-dev&lt;/code&gt; contains libraries concerning the PostgreSQL database, feel free to &lt;strong&gt;drop this if you are using some other database and install the requisite for that database&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;The flag &lt;code&gt;--no-install-recommends&lt;/code&gt; skips the installation of other recommended packages. This is done to reduce docker image size. Please note that dependent packages mandatory for our packages are still getting installed. &lt;code&gt;gettext&lt;/code&gt; is a Linux package that facilitates translations. If you want to know more refer &lt;a href="https://www.gnu.org/software/gettext/" rel="noopener noreferrer"&gt;here&lt;/a&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;apt-get purge -y --auto-remove -o \ APT::AutoRemove::RecommendsImportant=false* \
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In this command, we are cleaning up our package repository by removing orphaned packages we don’t need.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;rm -rf /var/lib/apt/lists/
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Cleaning &lt;code&gt;/var/lib/apt/lists/*&lt;/code&gt; can easily &lt;a href="https://askubuntu.com/questions/179955/var-lib-apt-lists-is-huge" rel="noopener noreferrer"&gt;reduce&lt;/a&gt; your docker image size by ~5%-25%. The &lt;code&gt;apt-get update&lt;/code&gt; command updates versions of the list of packages that are not required in our Dockerfile after installing &lt;code&gt;build-essential&lt;/code&gt; and &lt;code&gt;libpq-dev&lt;/code&gt; . Hence, in this step, we clean out all the files added.&lt;/p&gt;

&lt;h3&gt;
  
  
  Section 5- Project libraries and User Creation
&lt;/h3&gt;

&lt;p&gt;In this section, we install the project libraries mentioned in &lt;code&gt;requirements.txt&lt;/code&gt; and create a user who will be a non-root user for security purposes.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;COPY requirements.txt /tmp/requirements.txt
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you notice, instead of copying the whole project, which we do eventually in Section 6, we are only copying &lt;code&gt;requirements.txt&lt;/code&gt;. Then we are installing all the libraries mentioned in it. This is done so because Docker works on the principle of layers. If there is any change in a layer, all the subsequence layers will be re-processed. Hence, copying only &lt;code&gt;requirements.txt&lt;/code&gt; ensures that installation is reused across docker builds. This layer is dropped if there is a change in the &lt;code&gt;requirements.txt&lt;/code&gt; file itself. Had we copied the entire project of Section 6 here, each new commit or change in code would lead to invalidating of these layers and re-installation of libraries.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;RUN pip install --no-cache-dir -r /tmp/requirements.txt
&amp;amp;&amp;amp; rm -rf /tmp/requirements.txt \
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In this stage, we are installing all the project dependencies mentioned in &lt;code&gt;requirements.txt&lt;/code&gt;. The &lt;code&gt;--no-cache-dir&lt;/code&gt; flag is used to disable caching during pip installation. By default, pip caches installation files(&lt;code&gt;.whl&lt;/code&gt; etc) and source files(&lt;code&gt;.tar.gz&lt;/code&gt; etc). In docker installation, we don’t reinstall using the cache hence disabling it will reduce image size. Then we remove the requirements file we copied to /tmp directory&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;useradd -U app_user
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here, we are creating a non-root user &lt;code&gt;app_user&lt;/code&gt; using the &lt;code&gt;useradd&lt;/code&gt; command. By default, Docker runs container processes as root inside of a container. This is a bad practice since attackers can gain root access to the Docker host if they manage to break out of the container (&lt;a href="https://mherman.org/presentations/dockercon-2018/#58" rel="noopener noreferrer"&gt;source&lt;/a&gt;). The &lt;code&gt;-U&lt;/code&gt; flag creates a user group with the same name.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;install -d -m 0755 -o app_user -g app_user /app/static
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;At the end of the section, we are creating a folder &lt;code&gt;app/static&lt;/code&gt; and giving our user &lt;code&gt;app_user&lt;/code&gt; ownership to it. This folder will be used by Django to collect all static resources of our project by running the command &lt;code&gt;python manage.py collectstatic&lt;/code&gt; .&lt;/p&gt;

&lt;h3&gt;
  
  
  Section 6- Code and User Setup
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;WORKDIR ${APP_HOME}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We start this section by setting the working directory. The &lt;code&gt;WORKDIR&lt;/code&gt; instruction sets the working directory for subsequent commands. Since we don’t want to copy our code to the root folder, we are copying it to &lt;code&gt;/app&lt;/code&gt; folder.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;USER app_user:app_user
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then we are setting the non-root user created at the end of Section 5 as the owner of subsequent commands. As mentioned earlier, this will improve our security.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;COPY --chown=app_user:app_user . ${APP_HOME}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;With everything set up, we copy the project into the docker image. Any code change will only result in an update in this and subsequent layers of docker, hence resulting in reduced docker image build time. While copying we are providing the content’s ownership to our user &lt;code&gt;app_user&lt;/code&gt; created in Section 4.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;RUN chmod +x ./*.sh &amp;amp;&amp;amp; chmod +x ./postgresql/maintenance/*.sh &amp;amp;&amp;amp; \
    chmod +x ./postgresql/maintenance/_sourced/*.sh
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;At the end of this section, we are giving executable permission to our two scripts files i.e. &lt;code&gt;entrypoint.sh&lt;/code&gt; and &lt;code&gt;start.sh&lt;/code&gt; and all scripts we use to maintain our database. We will go into detail about these two files after the end of Section 6.&lt;/p&gt;

&lt;h3&gt;
  
  
  Section 7- Docker Run Checks and Configurations
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;ENTRYPOINT [ "./entrypoint.sh" ]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;ENTRYPOINT&lt;/code&gt; section of a Dockerfile is always executed, hence we would like to hitch it for validations and Django commands such as &lt;code&gt;migrate&lt;/code&gt;. The &lt;code&gt;CMD&lt;/code&gt; is overridden by the &lt;code&gt;command&lt;/code&gt; section in a &lt;code&gt;docker-compose&lt;/code&gt; file so the value given here, serves as a default.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;CMD [ "./start.sh", "server" ]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For a better understanding of what we are trying to do with &lt;code&gt;ENTRYPOINT&lt;/code&gt; and &lt;code&gt;CMD&lt;/code&gt; let’s look at the corresponding files &lt;code&gt;entrypoint.sh&lt;/code&gt; and &lt;code&gt;start.sh&lt;/code&gt; which are invoked by them.&lt;/p&gt;

&lt;h3&gt;
  
  
  entrypoint.sh
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;#!/bin/bash

set -o errexit
set -o pipefail
set -o nounset

postgres_ready() {
    python &amp;lt;&amp;lt; END
import sys
from psycopg2 import connect
from psycopg2.errors import OperationalError
try:
    connect(
        dbname="${DJANGO_POSTGRES_DATABASE}",
        user="${DJANGO_POSTGRES_USER}",
        password="${DJANGO_POSTGRES_PASSWORD}",
        host="${DJANGO_POSTGRES_HOST}",
        port="${DJANGO_POSTGRES_PORT}",
    )
except OperationalError:
    sys.exit(-1)
END
}

redis_ready() {
    python &amp;lt;&amp;lt; END
import sys
from redis import Redis
from redis import RedisError
try:
    redis = Redis.from_url("${CELERY_BROKER_URL}", db=0)
    redis.ping()
except RedisError:
    sys.exit(-1)
END
}

until postgres_ready; do
    &amp;gt;&amp;amp;2 echo "Waiting for PostgreSQL to become available..."
    sleep 5
done
&amp;gt;&amp;amp;2 echo "PostgreSQL is available"

until redis_ready; do
    &amp;gt;&amp;amp;2 echo "Waiting for Redis to become available..."
    sleep 5
done
&amp;gt;&amp;amp;2 echo "Redis is available"

python3 manage.py collectstatic --noinput

exec "$@"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Let’s look at the above &lt;code&gt;entrypoint.sh&lt;/code&gt;, though in lesser detail than &lt;code&gt;Dockerfile&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Docker provides a default entrypoint &lt;code&gt;/bin/sh&lt;/code&gt; . In most systems, it is a symbolic link, and in the case of Ubuntu it is linked to, &lt;code&gt;/bin/bash&lt;/code&gt; but in some scenarios, this assumption could be wrong(&lt;a href="https://askubuntu.com/a/141932" rel="noopener noreferrer"&gt;source&lt;/a&gt;). Hence we will be explicitly linking it to &lt;code&gt;/bin/bash&lt;/code&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Section 1- Bash options
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;set -o errexit
set -o pipefail
set -o nounset
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here, we are setting few bash options. The &lt;code&gt;errexit&lt;/code&gt; fails the script on the first encounter of error and doesn’t proceed further, which is default bash behavior. The &lt;code&gt;pipefail&lt;/code&gt; means that if any element of the pipeline fails, then the pipeline as a whole will fail. The &lt;code&gt;nounset&lt;/code&gt; forces error whenever an unset variable is extended.&lt;/p&gt;

&lt;h3&gt;
  
  
  Section 2: Health of dependent services
&lt;/h3&gt;

&lt;p&gt;Earlier, we had assumed that our application is using PostgreSQL database and Redis as celery backend. In this section, we are checking if both services are up and if not, we wait for them to come up.&lt;/p&gt;

&lt;p&gt;Similarly, you may add other such critical services which are necessary for the normal functioning of your application.&lt;/p&gt;

&lt;h3&gt;
  
  
  Section 3- Idempotent Django commands
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;python manage.py collectstatic --noinput
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;There are many Django management commands which we need to run before starting our Django server. This includes commands to collect all static resources, &lt;code&gt;collectstatic&lt;/code&gt;. Djangos &lt;code&gt;makemigrations&lt;/code&gt; and &lt;code&gt;migrate&lt;/code&gt; command should not be run at container runtime due to the following reasons:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;In dev environments you typically spin up one server, but in production you’re likely spinning up more than one. So now instead of one process doing schema migration, you have multiple processes trying to do multiple &lt;strong&gt;identical schema migrations&lt;/strong&gt; at the same time.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Depending on your database, the migration tool you’re using, and the kind of migration you’re doing, parallel schema upgrades might break your database in a variety of ways.&lt;br&gt;
    &lt;strong&gt;&lt;em&gt;You don’t want a broken database!&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;If you always do schema upgrades as part of the application startup you also end up mentally coupling schema migrations and code upgrades.*** In particular, you’ll start assuming that you only ever have new code running with the latest schema.***&lt;/p&gt;

&lt;p&gt;Why is that assumption a problem? From most to least common:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;&lt;em&gt;Sometimes you need to rollback a broken code upgrade.&lt;/em&gt;&lt;/strong&gt; If you assume you always have new code with a new schema, you can end up in a situation where your new code is broken, but you can’t easily rollback to older code because you’ve done an irreversible schema change.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;em&gt;To minimize downtime on upgrades, you want to have a brief moment where both old and new versions of your application are running in parallel.&lt;/em&gt;&lt;/strong&gt; If your schema migration breaks old code, you can’t do that.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;em&gt;To catch bugs in new code, you might want to do a canary deploy.&lt;/em&gt;&lt;/strong&gt; That is, upgrade only one or two of your many processes and see if they break.&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The only thing which should be kept in mind is that all these commands should be idempotent i.e. multiple runs of these commands should not have any side-effect on the state of our application. Idempotency is required here because, suppose if Kubernetes is scaling these containers, multiple instances will be running and they will interfere will each other.&lt;/p&gt;

&lt;p&gt;In fact, any idempotent operation can be executed here, not just Django commands.&lt;/p&gt;
&lt;h3&gt;
  
  
  start.sh
&lt;/h3&gt;

&lt;p&gt;We are using &lt;code&gt;start.sh&lt;/code&gt; file, to leverage the same Dockerfile and commands to run containers for Django server, Celery workers, Celery Beat and &lt;a href="https://flower.readthedocs.io/en/latest/" rel="noopener noreferrer"&gt;Flower&lt;/a&gt;, by having different arguments for each.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;#!/bin/bash

cd /app

if [ $# -eq 0 ]; then
    echo "Usage: start.sh [PROCESS_TYPE](server/beat/worker/flower)"
    exit 1
fi

PROCESS_TYPE=$1

if [ "$PROCESS_TYPE" = "server" ]; then
    if [ "$DJANGO_DEBUG" = "true" ]; then
        gunicorn \
            --reload \
            --bind 0.0.0.0:8000 \
            --workers 2 \
            --worker-class eventlet \
            --log-level DEBUG \
            --access-logfile "-" \
            --error-logfile "-" \
            dockerapp.wsgi
    else
        gunicorn \
            --bind 0.0.0.0:8000 \
            --workers 2 \
            --worker-class eventlet \
            --log-level DEBUG \
            --access-logfile "-" \
            --error-logfile "-" \
            dockerapp.wsgi
    fi
elif [ "$PROCESS_TYPE" = "beat" ]; then
    celery \
        --app dockerapp.celery_app \
        beat \
        --loglevel INFO \
        --scheduler django_celery_beat.schedulers:DatabaseScheduler
elif [ "$PROCESS_TYPE" = "flower" ]; then
    celery \
        --app dockerapp.celery_app \
        flower \
        --basic_auth="${CELERY_FLOWER_USER}:${CELERY_FLOWER_PASSWORD}" \
        --loglevel INFO
elif [ "$PROCESS_TYPE" = "worker" ]; then
    celery \
        --app dockerapp.celery_app \
        worker \
        --loglevel INFO --loglevel INFO -P gevent --concurrency=100

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

&lt;/div&gt;



&lt;p&gt;In the above script, we are using gunicorn to run our application server which is recommended approach for production. The &lt;code&gt;python manage.py runserver&lt;/code&gt; command should be used only in the development setup.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;PostgreSQL Docker Configuration&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Now lets take a look at our other dockerfile for our database&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# Step 1- Set arguments used throughout the build
ARG POSTGRES_VERSION=13.3-alpine

# Step 2- Set the postgresql base image
FROM postgres:${POSTGRES_VERSION}

# Step 3- Copy Postgresql configuration files and maintenance scripts

COPY ./postgresql/maintenance /usr/local/bin/maintenance
RUN chmod +x /usr/local/bin/maintenance/

RUN mv /usr/local/bin/maintenance/* /usr/local/bin \
&amp;amp;&amp;amp; rmdir /usr/local/bin/maintenance
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  &lt;strong&gt;Step 1 &amp;amp; Step 2 Argument Setup and Image Version&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;In steps 1 and 2 we are setting up argument and pulling PostgreSQL image from dockerhub&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Step 3 Copy Postgresql configuration files and maintenance scripts&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;In step 3 we are copying all config files and maintenance files for PostgreSQL to &lt;code&gt;/user/local/bin/&lt;/code&gt;This directory is where all binary files for linux are stored which makes it easier to invoke those scripts. Let's look at those scripts&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;backup.sh and backups.sh&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;These two bash scripts hold our backup-related scripts.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;working_dir="$(dirname ${0})"

source "${working_dir}/_sourced/constants.sh"
source "${working_dir}/_sourced/messages.sh"

message_welcome "Backing up the '${POSTGRES_DB}' database..."

if [[ "${POSTGRES_USER}" == "postgres" ]]; then
message_error "Backing up as 'postgres' user is not supported. Assign 'POSTGRES_USER' env with another one and try again."

exit 1

fi

export PGHOST="${POSTGRES_HOST}"
export PGPORT="${POSTGRES_PORT}"
export PGUSER="${POSTGRES_USER}"
export PGPASSWORD="${POSTGRES_PASSWORD}"
export PGDATABASE="${POSTGRES_DB}"

backup_filename="${BACKUP_FILE_PREFIX}_$(date +'%Y_%m_%dT%H_%M_%S').sql.gz"

pg_dump | gzip &amp;gt; "${BACKUP_DIR_PATH}/${backup_filename}"

message_success "'${POSTGRES_DB}' database backup '${backup_filename}' has been created and placed in '${BACKUP_DIR_PATH}'."
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We are exporting environment variables to connect to the database and preparing a backup filename from the date.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;pg_dump | gzip &amp;gt; “${BACKUP_DIR_PATH}/${backup_filename}”
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This command will dump all the content of the database to the backup file in the backup directory.&lt;/p&gt;

&lt;p&gt;To run our container we are running&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;docker-compose up
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The other essential commands are&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# To backup the database
docker-compose exec postgres backup

# To restore created backup
docker-compose exec postgres restore backup_2021_03_13T09_05_07.sql.gz
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Part I of this article is fairly long, We are going to leave it there for this one. In the next article, we are going to build our docker image and push it to DigitalOcean container registry. We will also setup CI/CD for the build process, after that we are going to deploy our docker image to DigitalOcean App platform and setup CI/CD for deployment using GitHub actions.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;a href="https://endalk200.medium.com/production-ready-docker-configuration-with-digitalocean-container-registry-part-ii-5361b8e6d5e0" rel="noopener noreferrer"&gt;Production-Ready Docker Configuration With DigitalOcean Container Registry Part II&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;To get the full code and try it for your self, It is on GitHub &lt;a href="https://github.com/endalk200/prod-django-docker-config" rel="noopener noreferrer"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Please comment on any gaps or improvements in the above setup. Follow me for more articles like this one.&lt;/p&gt;

&lt;p&gt;Use the following link and get 100 USD in DigitalOcean free credit.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.digitalocean.com/?refcode=7a5167a14566&amp;amp;utm_campaign=Referral_Invite&amp;amp;utm_medium=Referral_Program&amp;amp;utm_source=badge" rel="noopener noreferrer"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fweb-platforms.sfo2.cdn.digitaloceanspaces.com%2FWWW%2FBadge%25201.svg" alt="DigitalOcean Referral Badge"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>django</category>
      <category>docker</category>
      <category>production</category>
      <category>python</category>
    </item>
    <item>
      <title>Getting started with containerizing ReactJs application —  development and production environment setup.</title>
      <dc:creator>Endalkachew Biruk</dc:creator>
      <pubDate>Wed, 03 Nov 2021 11:42:29 +0000</pubDate>
      <link>https://dev.to/endalk200/getting-started-with-containerizing-reactjs-application-development-and-production-environment-setup-26c2</link>
      <guid>https://dev.to/endalk200/getting-started-with-containerizing-reactjs-application-development-and-production-environment-setup-26c2</guid>
      <description>&lt;h2&gt;
  
  
  &lt;strong&gt;Overview&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Before the wide adoption of containerization and docker developers develop their web apps and everything works perfectly in development machine but when they push it to the production environment it doesn’t work. This was because the development environment and production environment are not the same and that causes problems. There is also another issue if there is an error or a bug in the production environment it is very difficult to figure out what is wrong and solve that issue since that issue might not be in your local setup.&lt;/p&gt;

&lt;p&gt;This is where containerization technologies like docker come in. Docker solves the above issues by packaging your web app with all your dependencies and shipping it to production. This container is self-sufficient and can be run anywhere, The environment running the container doesn’t care what is in the container (It just works). When you use Docker for development and production you will not run into unforeseen production issues or bugs since you are using the same container you have been running locally in production.&lt;/p&gt;

&lt;h2&gt;
  
  
  Getting Started
&lt;/h2&gt;

&lt;p&gt;In this article, we are going to go over docker development and production docker setup for ReactJs applications. We will build a basic ReactJs application and containerize the app both for development and production. We will use &lt;code&gt;Nginx&lt;/code&gt; for serving production build of our ReactJs application.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Nginx is &lt;strong&gt;open-source software&lt;/strong&gt; and a web server for &lt;strong&gt;reverse proxying caching and load balancing&lt;/strong&gt;. Nginx also provides HTTP server capabilities. And it is mainly designed for maximum performance and stability. Nginx provides functions like &lt;strong&gt;IMAP, POP3, and SMTP&lt;/strong&gt; as a proxy server for email.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;If you want to clone the app and try it locally use the following git command. and check out the &lt;code&gt;reactjs-docker-setup&lt;/code&gt; branch.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;git clone [https://github.com/endalk200/blog-repository.git](https://github.com/endalk200/blog-repository.git)
cd ./blog-repository
git checkout reactjs-docker-setup
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We have two environments that our web app runs in. The first one is the development environment where we want hot reloading when making code changes. The other environment is the production environment. In production, our ReactJs app is optimized and built to static assets and served through a web server or a CDN. In our case, we are going to use &lt;code&gt;Nginx&lt;/code&gt; to serve our static assets.&lt;/p&gt;

&lt;p&gt;We are going to make sure both our production and development docker configurations are as close to each other as possible to avoid unforeseen issues once deployed.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;When we build our react application the output is optimized static assets (html, css and js file). To serve these files we are going to use Nginx, Popular web server and reverse proxy server.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Our file structure looks like this&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--IfHMNTU9--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn.hashnode.com/res/hashnode/image/upload/v1635936347576/w0Wrkvbbw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--IfHMNTU9--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn.hashnode.com/res/hashnode/image/upload/v1635936347576/w0Wrkvbbw.png" alt="File structure" width="451" height="362"&gt;&lt;/a&gt;&lt;em&gt;File structure&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;The most important files we need to see are &lt;code&gt;Dockerfile&lt;/code&gt; both in local and production directory and&lt;code&gt;docker-compose.yaml&lt;/code&gt; file. Let’s break it down depending on the environment.&lt;/p&gt;

&lt;h2&gt;
  
  
  Development
&lt;/h2&gt;

&lt;p&gt;Since in development we want &lt;code&gt;hot realoading&lt;/code&gt; we are going to mount our local directory to our container. We will achieve this using &lt;code&gt;docker-compose.yaml&lt;/code&gt; file. Let’s start with our dockerfile.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;FROM node:alpine AS dependencies
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We are going to use &lt;code&gt;alpine&lt;/code&gt; as a base image. It is a minimal Linux build with necessary packages. We are going to use a multi-stage build and we will name this stage dependencies where we install all OS level and application dependencies.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;RUN apk add --no-cache libc6-compat
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;libc6-compat&lt;/code&gt; is needed in nodeJs build systems. If you want to now more about this refer &lt;a href="https://github.com/nodejs/docker-node/tree/b4117f9333da4138b03a546ec926ef50a31506c3#nodealpine"&gt;here&lt;/a&gt;&lt;br&gt;
&lt;/p&gt;

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

&lt;/div&gt;



&lt;p&gt;We are going to set our working directory to &lt;code&gt;/app&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;COPY package.json package-lock.json ./
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then we are going to copy our &lt;code&gt;package.json&lt;/code&gt; and &lt;code&gt;package-lock.json&lt;/code&gt; files to install our app dependencies.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;RUN npm ci
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This command is similar to &lt;code&gt;[npm install&lt;/code&gt;](&lt;a href="https://docs.npmjs.com/cli/v7/commands/npm-install"&gt;https://docs.npmjs.com/cli/v7/commands/npm-install&lt;/a&gt;), except it's meant to be used in automated environments such as &lt;strong&gt;test platforms&lt;/strong&gt;, &lt;strong&gt;continuous integration&lt;/strong&gt;, and &lt;strong&gt;deployment&lt;/strong&gt; -- or any situation where you want to make sure you're doing a clean install of your dependencies.&lt;/p&gt;

&lt;p&gt;In short, the main differences between using &lt;code&gt;npm install&lt;/code&gt; and &lt;code&gt;npm ci&lt;/code&gt; are:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;The project &lt;strong&gt;must&lt;/strong&gt; have an existing &lt;code&gt;package-lock.json&lt;/code&gt; or &lt;code&gt;npm-shrinkwrap.json&lt;/code&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;If dependencies in the package-lock do not match those in &lt;code&gt;package.json&lt;/code&gt;, &lt;code&gt;npm ci&lt;/code&gt; will exit with an error, instead of updating the package-lock.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;npm ci&lt;/code&gt; can only install entire projects at a time: individual dependencies cannot be added with this command.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;If a &lt;code&gt;node_modules&lt;/code&gt; is already present, it will be automatically removed before &lt;code&gt;npm ci&lt;/code&gt; begins its install.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;It will never write to &lt;code&gt;package.json&lt;/code&gt; or any of the package-locks: installs are essentially frozen.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Unto the second stage which is the runner stage, where we run our application.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;FROM node:alpine AS runner

WORKDIR /app

COPY . .

COPY --from=dependencies /app/node_modules ./node_modules
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In the above config, we are setting the working directory where we run our application to &lt;code&gt;/app&lt;/code&gt;. Then we are copying all files in our local directory to the container. NOTE: All files in&lt;code&gt;.dockerignore&lt;/code&gt; file will not be added to the container.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;ENTRYPOINT ["npm", "run", "start"]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The last one will be our &lt;code&gt;ENTRYPOINT&lt;/code&gt; . This is where the command to run the application goes. &lt;code&gt;npm run start&lt;/code&gt; will run our web app locally.&lt;/p&gt;

&lt;p&gt;Now that we have seen our &lt;code&gt;Dockerfile&lt;/code&gt; we are going to see out &lt;code&gt;docker-compose.yaml&lt;/code&gt; file.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;version: '3'

services:
    web:
        build:
            context: .
            dockerfile: ./local/Dockerfile
    image: reactapp_image
    container_name: reactapp_container
    ports:
        - 3000:3000
    volumes:
        - ./:/app
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Let’s break this down. basically, we are telling Docker to use the current directory as a context where to run everything and use the &lt;code&gt;Dockerfile&lt;/code&gt; found in the &lt;code&gt;local&lt;/code&gt; directory. Then we are telling docker to name the image built &lt;code&gt;reactapp_image&lt;/code&gt; and the container &lt;code&gt;reactapp_container&lt;/code&gt; We are also telling docker to map our local machines port &lt;code&gt;3000&lt;/code&gt; to the containers port&lt;code&gt;3000&lt;/code&gt; . Then since we want all code changes we make locally to be reflected in our dev server we are going to map our current directory to the containers &lt;code&gt;/app&lt;/code&gt; directory where our application runs in.&lt;/p&gt;

&lt;p&gt;To run our development server for the first time we have to build our image and spin it up. To do that we will execute the following command.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;docker-compose up --build
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;After that first time, you just have to run &lt;code&gt;docker-compose up&lt;/code&gt; to spin up the container.&lt;/p&gt;

&lt;p&gt;To tear down the running container use the command.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;docker-compose down
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For some reason, if you have to run some kind of command inside the container, first run &lt;code&gt;docker ps&lt;/code&gt; to list all running containers with their container ID. Then use the ID and run the following command.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;docker exec -ti f6d6a1d9a076 bash
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Assuming &lt;code&gt;f6d6a1d9a076&lt;/code&gt; is your container ID it will open up an interactive bash session where you can run your commands right in the container.&lt;/p&gt;

&lt;h2&gt;
  
  
  Production
&lt;/h2&gt;

&lt;p&gt;Now that we have seen our development docker config let’s see the production one. The production docker config only needs the &lt;code&gt;Dockerfile&lt;/code&gt; to run.&lt;/p&gt;

&lt;p&gt;The first stage of our &lt;code&gt;Dockerfile&lt;/code&gt; is the same as the above config. Let's start with the build stage.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;FROM node:alpine AS builder

WORKDIR /app

COPY . .

COPY --from=dependencies /app/node_modules ./node_modules

RUN npm run build &amp;amp;&amp;amp; npm install --production --ignore-scripts --prefer-offline
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In this stage, we are choosing &lt;code&gt;alpine&lt;/code&gt; as build stage base image. We are also setting the working directory to &lt;code&gt;/app&lt;/code&gt; then we are copying all files in the current directory to the &lt;code&gt;/app&lt;/code&gt; directory. After that, we are copying all dependencies downloaded and stored in the &lt;code&gt;/app/node_modules&lt;/code&gt; directory to &lt;code&gt;node_modules&lt;/code&gt; directory from the previous &lt;code&gt;dependencies&lt;/code&gt; stage.&lt;/p&gt;

&lt;p&gt;After that, we are running &lt;code&gt;npm run build&lt;/code&gt; after &lt;code&gt;npm install --production --ignore-scripts --prefer-offline&lt;/code&gt;This will build an optimized build of our ReactJs application.&lt;/p&gt;

&lt;p&gt;The next stage is where we run our web server using &lt;code&gt;Nginx&lt;/code&gt; This is where things get interesting. We are going to use the default &lt;code&gt;Nginx&lt;/code&gt; config since we don’t need anything other than that to run our app.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;Nginx&lt;/code&gt; has some default configs and behaviors we need to know. Before getting into our docker config let’s see a few of them.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;Nginx&lt;/code&gt; serves static assets found in &lt;code&gt;/usr/share/nginx/html&lt;/code&gt; directory. So all static assets like HTML, CSS, and Js need to be in this directory in order for&lt;code&gt;Nginx&lt;/code&gt; to serve them (We can also change this behavior by editing the default config file). By default &lt;code&gt;Nginx&lt;/code&gt; runs on port 80&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;*# Nginx configuration and runing stage.
*FROM nginx:alpine AS runner

# Set working directory to nginx asset directory
WORKDIR /usr/share/nginx/html

# Remove default nginx static assets
RUN rm -rf ./*

# Copy static assets from builder stage
COPY --from=builder /app/build .

# Containers run nginx with global directives and daemon off
ENTRYPOINT ["nginx", "-g", "daemon off;"]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We are choosing &lt;code&gt;nginx:alpine&lt;/code&gt; as our runner since it has all packages we need and it is minimal in size.&lt;/p&gt;

&lt;p&gt;We are also setting our working directory to &lt;code&gt;/user/share/nginx/html&lt;/code&gt; the default location where static assets are served from. Then we are removing all assets found in that directory using this directive &lt;code&gt;RUN rm -rf ./*&lt;/code&gt; . Then we will copy our optimized build from the builder stage to the current working directory. Then we are going to run &lt;code&gt;Nginx&lt;/code&gt; web server using the command &lt;code&gt;nginx -g daemon off&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;To build our docker image from this config run&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;docker build -t reactjs-prod -f ./production/Dockerfile .
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We are naming the image &lt;code&gt;reactjs-prod&lt;/code&gt; and we are going to use the production Dockerfile in the production directory.&lt;/p&gt;

&lt;p&gt;To run the built image in interactive mode we will use the following docker command.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;docker run -it -p 80:80 reactjs-prod:latest
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;-it&lt;/code&gt; flag tells docker to run the container in interactive mode so that we can see the log. The &lt;code&gt;-p&lt;/code&gt; flag tells docker to map port 80 of our machine to port 80 of our container. This command will spin up the production docker container running &lt;code&gt;Nginx&lt;/code&gt; server.&lt;/p&gt;

&lt;h3&gt;
  
  
  Where to go from here
&lt;/h3&gt;

&lt;p&gt;If you want more control over how &lt;code&gt;Nginx&lt;/code&gt; serves the static assets and how it behaves you can replace the default &lt;code&gt;Nginx&lt;/code&gt; config file find in &lt;code&gt;/etc/nginx/nginx.conf&lt;/code&gt; with your config file. As an example, you can customize the above runner stage as follows.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;*# Nginx configuration and runing stage.
*FROM nginx:alpine AS runner

# Set working directory to nginx asset directory
WORKDIR /usr/share/nginx/html

# Remove default nginx static assets
RUN rm -rf ./*

# Remove the default nginx config file
RUN rm -rf /etc/nginx/nginx.conf

# Copy custom nginx config to the directory
COPY ./nginx/nginx.con /etc/nginx/

# Copy static assets from builder stage
COPY --from=builder /app/build .

# Containers run nginx with global directives and daemon off
ENTRYPOINT ["nginx", "-g", "daemon off;"]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The above config assumes you have a custom &lt;code&gt;Nginx&lt;/code&gt; config in &lt;code&gt;nginx&lt;/code&gt; directory.&lt;/p&gt;

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

&lt;p&gt;That's it for this one, If you want more explanation on this article leave a comment and I will get back to you.&lt;/p&gt;

&lt;p&gt;To get the full code and try it for yourself, It is on GitHub &lt;a href="https://github.com/endalk200/blog-repository/"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Please comment on any gaps or improvements or just tell me your thoughts down in the comments. Follow me for more in-depth articles like this one.&lt;/p&gt;

&lt;p&gt;Use the following link and get 100 USD in DigitalOcean free credit.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.digitalocean.com/?refcode=713dfe72e086&amp;amp;utm_campaign=Referral_Invite&amp;amp;utm_medium=Referral_Program&amp;amp;utm_source=badge"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--YS4lrG-m--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://web-platforms.sfo2.digitaloceanspaces.com/WWW/Badge%25203.svg" alt="DigitalOcean Referral Badge" width="200" height="65"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>react</category>
      <category>javascript</category>
      <category>docker</category>
      <category>nginx</category>
    </item>
  </channel>
</rss>
