<?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: Roman Sarder</title>
    <description>The latest articles on DEV Community by Roman Sarder (@romansarder).</description>
    <link>https://dev.to/romansarder</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%2F693242%2F788047c2-6ed4-4e7a-be79-6206cfdbce1a.jpeg</url>
      <title>DEV Community: Roman Sarder</title>
      <link>https://dev.to/romansarder</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/romansarder"/>
    <language>en</language>
    <item>
      <title>The saga of async JavaScript: CSP</title>
      <dc:creator>Roman Sarder</dc:creator>
      <pubDate>Thu, 01 Dec 2022 01:27:49 +0000</pubDate>
      <link>https://dev.to/romansarder/the-saga-of-async-javascript-csp-75e</link>
      <guid>https://dev.to/romansarder/the-saga-of-async-javascript-csp-75e</guid>
      <description>&lt;h2&gt;
  
  
  Intro
&lt;/h2&gt;

&lt;p&gt;In a &lt;a href="https://dev.to/romansarder/the-saga-of-async-javascript-generators-5dhi"&gt;previous series&lt;/a&gt;, we discovered that it is indeed possible to write our async code in a synchronous fashion using a combination of promises and generators. Our enhanced functions can run asynchronously and independently with the ability to pause and resume on demand. They are much like isolated mini-programs inside our main program! But when you start writing some real-world scenarios, you stumble upon a situation when those tiny independent bits need to communicate with each other and synchronize their execution. In this article we will introduce ourselves to a new pattern that will hopefully allow us to structure our async code with generators in a convenient and scalable way, solving the most common challenges that concurrency presents to us.&lt;/p&gt;

&lt;h2&gt;
  
  
  What is CSP
&lt;/h2&gt;

&lt;p&gt;CSP stands for &lt;strong&gt;Communicating Sequential Processes&lt;/strong&gt; and is yet another way to model concurrency in our application. CSP is about decomposing your program into a set of independent, self-contained, black-box &lt;strong&gt;processes&lt;/strong&gt; which respond to various events and produce events themselves. To allow these processes to communicate we use &lt;strong&gt;channels&lt;/strong&gt; - a middleman entity that acts like a pipe and distributes events between processes. The way interaction with channels works makes up most of the pattern. There is a strong mathematical theory behind CSP which defines a set of laws and abstractions to make it work but thankfully we don't have to be Ph.D. in Maths to start using it.&lt;/p&gt;

&lt;h2&gt;
  
  
  An overview
&lt;/h2&gt;

&lt;p&gt;In the real world, things communicate with each other and respond to events. We even tend to think about many things in terms of how they react to events. How could we adopt the right mindset to view the real-world object as a process? We may try to think of something as a &lt;strong&gt;set of its reactions to events&lt;/strong&gt;. Let's imagine a coffee machine. When you turn it on, it heats the water. When you click "Latte", it makes a latte. What about us? When we want a coffee, we go to the coffee machine and make a coffee. When coffee is ready, we drink it. You and a coffee machine are just two processes communicating with each other through an interface. It is the interface that synchronize your actions, and let's you know when the coffee machine finished heating and is ready for you to choose a coffee. Otherwise, without knowing how the mechanism works, your actions would be chaotic and out of order resulting in a broken coffee machine and a solid paycheck. In this particular case, an interface acts like an &lt;strong&gt;event channel&lt;/strong&gt; for the actual coffee-making mechanism inside of our machine and the person. We surely don't need to know about what makes us a coffee behind the curtains as long as we know how to respond to events that it communicates to us.&lt;/p&gt;

&lt;h2&gt;
  
  
  What is a channel
&lt;/h2&gt;

&lt;p&gt;You can think of a channel as an array of constantly updating pieces of data or events. It might be also similar to a queue in some sense. Anyway, channels represent asynchronous communication between your code. You can &lt;strong&gt;take&lt;/strong&gt; it from the channel and you can &lt;strong&gt;put&lt;/strong&gt; something into the channel. Channels can be buffered or unbuffered, and the buffers can be of different kinds. For example dropping buffer, when full, will drop all incoming values. The sliding buffer will accept an incoming value and drop the oldest element in the buffer. Why would you need buffers? Imagine yourself being a bartender and getting an order for Mojito. Once you are done with Mojito, you ring the bell and expect your order to be taken. Would you sit and wait for somebody to take it before processing other orders? Surely not, you can fit 10 Mojitos on your bar counter, so your "buffer" capacity is 10.&lt;/p&gt;

&lt;h2&gt;
  
  
  Guarded commands
&lt;/h2&gt;

&lt;p&gt;As we said above, CSP enforces a set of rules when it comes to communication and channels. One of the most important ones is the notion of &lt;strong&gt;back pressure&lt;/strong&gt;. Imagine two people standing on opposite sides of the pipe each having a tap. We cannot push the water to the person on the opposite side &lt;strong&gt;until he turns the tap&lt;/strong&gt; and allows us to deliver it. &lt;strong&gt;We need to wait for it.&lt;/strong&gt; Guarded commands in most of the CSP implementations feature the same concept. We have to wait for somebody to be ready to take out the event from the channel before completing our &lt;strong&gt;put&lt;/strong&gt; operation. The sender process is essentially blocked at this point. When a process wants to receive a an event, it will be blocked as well until an event arrives at the channel. Guarded commands act like a synchronization mechanism that lets two otherwise mostly independent processes sync on particular events.&lt;/p&gt;

&lt;h2&gt;
  
  
  Show me an example
&lt;/h2&gt;

&lt;p&gt;While learning a pattern, I attempted to create a bare-bones implementation of CSP. Besides getting a deeper understanding of the pattern, another important benefit is that I can show you examples with this library. The code illustrates a super simple coffee machine example I was talking about 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="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;makeChannel&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;csp-coffee/channel&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;take&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;put&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;csp-coffee/operators&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;go&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;csp-coffee/go&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;delay&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;csp-coffee/utils&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;coffeeMachineInterface&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;makeChannel&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;string&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;function&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="nx"&gt;person&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;yield&lt;/span&gt; &lt;span class="nx"&gt;put&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;coffeeMachineInterface&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;latte&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;i want my coffee so much&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;yield&lt;/span&gt; &lt;span class="nx"&gt;take&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;coffeeMachineInterface&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;yummy&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="o"&gt;*&lt;/span&gt; &lt;span class="nx"&gt;coffeeMaker&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;coffeeToMake&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;string&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;yield&lt;/span&gt; &lt;span class="nx"&gt;take&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;coffeeMachineInterface&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;yield&lt;/span&gt; &lt;span class="nx"&gt;delay&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1000&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;yield&lt;/span&gt; &lt;span class="nx"&gt;put&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;coffeeMachineInterface&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;`have a coffee &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;coffeeToMake&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;cancellablePromise&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;personPromise&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;go&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;person&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;cancellablePromise&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;coffeeMakerPromise&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;go&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;coffeeMaker&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="nb"&gt;Promise&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;all&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="nx"&gt;personPromise&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;coffeeMakerPromise&lt;/span&gt;&lt;span class="p"&gt;]).&lt;/span&gt;&lt;span class="nx"&gt;then&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;done&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Note that we expressed our actors as generator functions that are later passed to a special &lt;code&gt;go&lt;/code&gt; function. This is what turns our generators into &lt;strong&gt;processes&lt;/strong&gt;. It just takes care of promises, library operators (&lt;strong&gt;put&lt;/strong&gt;, &lt;strong&gt;take&lt;/strong&gt;), and the correct order of their execution. It also returns a promise which resolves when the generator functions is done executing which is handy if we would try to incorporate this library into our code with heavy promise usage.&lt;/p&gt;

&lt;h2&gt;
  
  
  How does it make things better?
&lt;/h2&gt;

&lt;p&gt;It is not, it is just a different way to organize your asynchronous code. Of course, you would not need such kind of abstraction in every single case. But at some point in developing pretty much any sizeable application, you have to deal with increasing numbers of concurrency problems. And when trying to solve these problems using promises, RxJS, or plain callbacks, you start putting your business code into event handlers. With a growing amount of such code, it is becoming harder and harder to reason about your business logic since you have to assemble a puzzle of callbacks spread all over your application. CSP tackles this issue by introducing channels in the middle, which separates concerns of communication and flow control. It takes all of the good parts of generators - synchronous-looking code, pausing, etc - and takes it to the next level by providing an abstraction for communication and a clear set of rules for it.&lt;/p&gt;

&lt;h2&gt;
  
  
  Outro
&lt;/h2&gt;

&lt;p&gt;This article appeared to be much shorter than I had previously expected. The amount of methods and functions that CSP might provide to you is overwhelming for one article. What's important is that you are not required to know them all to understand the concept. We took what we learned from the previous article about generators and saw how it could evolve into a much more serious tool. I will leave a few links below for you to explore the API and get a better understanding of what an implementation might be capable of.&lt;/p&gt;

&lt;h3&gt;
  
  
  Resources
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://github.com/RomanSarder/csp-coffee"&gt;My attempt to port parts of Core Async to JavaScript&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/clojure/core.async"&gt;Clojure Core Async Library&lt;/a&gt;&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>programming</category>
      <category>webdev</category>
      <category>architecture</category>
    </item>
    <item>
      <title>The saga of async JavaScript: Generators</title>
      <dc:creator>Roman Sarder</dc:creator>
      <pubDate>Mon, 27 Sep 2021 15:28:59 +0000</pubDate>
      <link>https://dev.to/romansarder/the-saga-of-async-javascript-generators-5dhi</link>
      <guid>https://dev.to/romansarder/the-saga-of-async-javascript-generators-5dhi</guid>
      <description>&lt;h2&gt;
  
  
  Intro
&lt;/h2&gt;

&lt;p&gt;One of the most complex things in modern JavaScript programs is asynchronicity. We have already taken a look at a couple of existing patterns such as &lt;a href="https://dev.to/romansarder/the-saga-of-async-javascript-callbacks-13nk"&gt;Callbacks&lt;/a&gt;, &lt;a href="https://dev.to/romansarder/the-saga-of-async-javascript-thunks-4i03"&gt;Thunks&lt;/a&gt;, and &lt;a href="https://dev.to/romansarder/the-saga-of-async-javascript-promises-2n3i"&gt;Promises&lt;/a&gt;. Although they managed to solve a few key problems, all of these patterns have one major thing in common - they don't look like synchronous code. There has always been a difference between how we write and reason about our asynchronous code. This might sound like an unreal thing to wish for but time proved that we can get really close to it. &lt;/p&gt;

&lt;h2&gt;
  
  
  What we will learn
&lt;/h2&gt;

&lt;p&gt;In today's article, we will talk about &lt;strong&gt;Generators&lt;/strong&gt;. It's a new type of function introduced in ES6. At first, as we look at it, it will not be immediately obvious how it has anything to do with asynchronous programming. It will most likely seem weird to many of you. But as we slowly going through explanations and examples, we will eventually get to the point where it completely makes sense why we need them in our code. You will discover what makes &lt;strong&gt;Generators&lt;/strong&gt; really stand out and what problems they solve for us. In the end, hopefully, you will be able to articulate about &lt;strong&gt;Generators&lt;/strong&gt; with confidence and justify their usage in your code&lt;/p&gt;

&lt;h2&gt;
  
  
  Run-to-completion semantics
&lt;/h2&gt;

&lt;p&gt;All normal functions in JavaScript have a common notable feature. When writing our synchronous code, we know that when our function starts executing it will always run to the end and finish before any other function gets a chance to execute. At any given second only one function is able to actively execute. That also means that nothing can pre-emptively interrupt our functions to run something else. The academic term that would perfectly describe all said above is &lt;strong&gt;run-to-completion semantics&lt;/strong&gt;. This is what helps us to not worry about two functions interrupting each other or corrupt our shared memory. By having this "rule" in JavaScript we are able to reason about our code in a pure single-threaded fashion.&lt;/p&gt;

&lt;h2&gt;
  
  
  Generators are not like that
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Generators&lt;/strong&gt; are a very different type of thing. They &lt;strong&gt;don't meet this run-to-completion&lt;/strong&gt; rule at all. On the surface, it should have brought quite a bit of chaos into our code. But it appears that they provide yet another way to solve our problems, although the way itself might look a bit strange. One way to explain Generators would be to say that in current JavaScript they let us define a &lt;strong&gt;state machine&lt;/strong&gt; - a series of flow from one state to another state with an ability to declaratively list those transitions. I am sure that most of you created quite a few state machines and you might not even know that it is called this way. Previously, there were a lot of efforts and time involved in implementing state machines using available tools in JavaScript. We often used a &lt;strong&gt;closure&lt;/strong&gt; to maintain a current and previous state in a function making all of those transitions, but the code was getting complex, and writing it was time-consuming as well. &lt;strong&gt;Generators&lt;/strong&gt; are adding syntactic sugar which lets you solve the same problem in a lot easier and clear way. But how does that help with async code? To get there, we first need to get a good grasp on the internal plumbings of Generators.&lt;/p&gt;

&lt;h2&gt;
  
  
  Pausing with yield
&lt;/h2&gt;

&lt;p&gt;Generators introduce a new keyword called &lt;code&gt;yield&lt;/code&gt; and it acts a lot like a pause button. So when the generator function is running and it would come across a &lt;code&gt;yield&lt;/code&gt; keyword it would demonstrate an interesting behavior. It does not matter where this yield is encountered. It might be even in the middle of an expression, but the generator will &lt;strong&gt;pause&lt;/strong&gt;. From that point nothing will happen in a generator itself, it will stay completely blocked. It literally gets &lt;strong&gt;frozen&lt;/strong&gt;. The important part is that the overall program itself is not blocked and can continue running. The block caused by yield is completely localized. And it can stay in this "paused" state indefinitely until somebody will come and tell it to continue running. You can think of a &lt;strong&gt;Generator&lt;/strong&gt; as a function that can pause and resume as many times as necessary without losing any internal state.&lt;/p&gt;

&lt;h2&gt;
  
  
  An example
&lt;/h2&gt;

&lt;p&gt;We now have to take a look at an example of &lt;strong&gt;Generator&lt;/strong&gt; to see how all of these concepts stack together. Here is our first generator:&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="o"&gt;*&lt;/span&gt; &lt;span class="nx"&gt;helloWorldGenerator&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="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Hello world&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="k"&gt;yield&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// pausing&lt;/span&gt;
  &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Hello again!&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;On line 1, the asterisk symbol tells the JavaScript that the function we are defining is indeed a generator. You will notice on line 3 we have our yield keyword which is our &lt;strong&gt;pause&lt;/strong&gt; button. By using yield, the generator itself declares when, where, and in which manner it wants to pause. This is also called &lt;strong&gt;cooperative multitasking&lt;/strong&gt;. Nobody on the outside can come in and interrupt its execution. This is what often causes catastrophes in multi-threaded languages. Fortunately, we don't have those.&lt;/p&gt;

&lt;h2&gt;
  
  
  Calling a Generator
&lt;/h2&gt;

&lt;p&gt;When calling a Generator it behaves a bit different than other functions. Continuing with an example above, let's illustrate how we could use that generator:&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;iterator&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;helloWorldGenerator&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

&lt;span class="nx"&gt;iterator&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;next&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="c1"&gt;// Hello world&lt;/span&gt;
&lt;span class="nx"&gt;iterator&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;next&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="c1"&gt;// Hello again!&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;When we call the generator function, no code gets executed inside the generator itself. Executing a generator actually does not run any code. What's really happening is that we are getting an &lt;strong&gt;iterator&lt;/strong&gt;. You probably know what are iterators, but just in case let's recall their definition. &lt;strong&gt;Iterator&lt;/strong&gt; is a way of stepping through the set of data one result at a time. In this case, the purpose of the iterator is not to step through a collection of items, but to control our generator from the outside by literally stepping through these yield statements. Think of it as a handy API that helps us to control the flow of our generator. We &lt;strong&gt;can't pause&lt;/strong&gt; a generator, but using an iterator we can ask it to run until it wants to &lt;strong&gt;pause itself&lt;/strong&gt;. So on Line 1 none of the code runs, but on Line 2, by calling &lt;code&gt;.next&lt;/code&gt; on the iterator object, we start the generator's execution. It will then execute &lt;code&gt;console.log('Hello world')&lt;/code&gt; statement, pause itself on yield and return control back to the client's code. Whenever the next call to &lt;code&gt;.next&lt;/code&gt; happens, it will resume the generator, execute the last &lt;code&gt;console.log('Hello again!')&lt;/code&gt; statement and at this point, our generator is done.&lt;/p&gt;

&lt;h2&gt;
  
  
  Yielding values
&lt;/h2&gt;

&lt;p&gt;It appears that in addition to &lt;strong&gt;yielding control&lt;/strong&gt; to our code, generators are also able to &lt;strong&gt;yield values&lt;/strong&gt; as well. In our previous example, we yielded nothing. Let's come up with a dummy example to showcase this point:&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="o"&gt;*&lt;/span&gt; &lt;span class="nx"&gt;authorDossierGenerator&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;author&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Roman&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;surname&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Sarder&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;age&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;23&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="k"&gt;yield&lt;/span&gt; &lt;span class="nx"&gt;author&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="k"&gt;yield&lt;/span&gt; &lt;span class="nx"&gt;author&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;surname&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="k"&gt;yield&lt;/span&gt; &lt;span class="nx"&gt;author&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;age&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;iterator&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;authorDossierGenerator&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="nx"&gt;iterator&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;next&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="c1"&gt;// { value: "Roman", done: false }&lt;/span&gt;
&lt;span class="nx"&gt;iterator&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;next&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="c1"&gt;// { value: "Sarder", done: false }&lt;/span&gt;
&lt;span class="nx"&gt;iterator&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;next&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="c1"&gt;// { value 23, done: false }&lt;/span&gt;
&lt;span class="nx"&gt;iterator&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;next&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="c1"&gt;// { value: undefined, done: true }&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In the last example we assumed that generator yielded us an &lt;code&gt;undefined&lt;/code&gt;, but now we are returning actual values. You will notice that each &lt;code&gt;.next&lt;/code&gt; call gives us an object with value and done properties. The value corresponds to what we are &lt;strong&gt;yielding&lt;/strong&gt; from the generator, in this case, it's a bunch of object property values. The done flag indicates whether the generator is complete or not. This might be tricky at the beginning. Our third &lt;code&gt;iterator.next&lt;/code&gt; call visually might look like a generator is already done, but it is not. Although it is the last line in the generator, what really happens is that the generator is paused on the last expression which is &lt;code&gt;yield author.age&lt;/code&gt;. If it is paused, it can be resumed and that's why only after the fourth &lt;code&gt;.nex&lt;/code&gt;t we are getting &lt;code&gt;done: false&lt;/code&gt;. But what about the last value being undefined? As with simple functions, if there is no return statement at the end of the generator, JavaScript assumes that it returns undefined. At any point, you can return from a generator and it will immediately &lt;strong&gt;complete&lt;/strong&gt; itself as well as return a value if any. Think of return as an &lt;strong&gt;"Exit"&lt;/strong&gt; button.&lt;/p&gt;

&lt;h2&gt;
  
  
  Passing values
&lt;/h2&gt;

&lt;p&gt;We managed to illustrate that there is indeed a way for a generator to pass messages to the client's code. But not only we can &lt;strong&gt;yield&lt;/strong&gt; messages out, but when calling the &lt;code&gt;.next&lt;/code&gt; method we can also &lt;strong&gt;pass the message in&lt;/strong&gt; and that message goes right into the generator.&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="o"&gt;*&lt;/span&gt; &lt;span class="nx"&gt;sumIncrementedNumbers&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;x&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;yield&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;y&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;yield&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="k"&gt;yield&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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;iterator&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;sumIncrementedNumbers&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

&lt;span class="nx"&gt;iterator&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;next&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="c1"&gt;// { value: undefined, done: false } &lt;/span&gt;
&lt;span class="nx"&gt;iterator&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;next&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;// { value: undefined, done: false }&lt;/span&gt;
&lt;span class="nx"&gt;iterator&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;next&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="c1"&gt;// { value: 9, done: false }&lt;/span&gt;
&lt;span class="nx"&gt;iterator&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;next&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="c1"&gt;// { value: undefined, done: true }&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Notice that we placed our yield keywords in the middle of both expressions. From the inside perspective, think of those yields as &lt;strong&gt;question marks&lt;/strong&gt;. When the generator gets to the first expression it basically asks a question: Which value should go here? Without an answer, it cannot complete an expression. At this point, it will pause itself and wait for somebody to provide this value. And we do that by calling &lt;code&gt;.next&lt;/code&gt; and passing a value of &lt;code&gt;5&lt;/code&gt;. Now it can proceed to the next &lt;code&gt;yield&lt;/code&gt;. Those yields act like &lt;strong&gt;placeholders&lt;/strong&gt; for values that will at some point in time be passed to the generator and replace yield to complete an expression.&lt;/p&gt;

&lt;h2&gt;
  
  
  Converting to async
&lt;/h2&gt;

&lt;p&gt;Right now, you should be ready to look at the following example and not have your head completely blown up. We are going to attempt to use &lt;strong&gt;Generators&lt;/strong&gt; to work with &lt;strong&gt;asynchronous&lt;/strong&gt; code and convert one of our previous examples. It might look a bit awful because of hoisting but think of it as a proof of concept. We will surely refactor into something that looks a lot nicer.&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="nx"&gt;getData&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;number&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;setTimeout&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;iterator&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;next&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;number&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="mi"&gt;1000&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="nx"&gt;sumIncrementedNumbersAsync&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;x&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;yield&lt;/span&gt; &lt;span class="nx"&gt;getData&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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;y&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;yield&lt;/span&gt; &lt;span class="nx"&gt;getData&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;20&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;

  &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="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="c1"&gt;// 32&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;iterator&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;sumIncrementedNumbersAsync&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="nx"&gt;iterator&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;next&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Phew, are you still there? Let's walk through each line of code to get an idea of what's happening. First, we call our generator to produce an iterator and start execution by calling &lt;code&gt;.next&lt;/code&gt;. So far so good, no rocket science evolved. Our generator starts calculating a value of &lt;code&gt;x&lt;/code&gt; and encounters the first &lt;code&gt;yield&lt;/code&gt;. Now the generator is &lt;strong&gt;paused&lt;/strong&gt; and asks a question: What value should go here? The answer lies in a result of &lt;code&gt;getData(10)&lt;/code&gt; function call. Here comes the interesting part: our homemade getData function, which is a fake async function, &lt;strong&gt;resumes a generator once it is done with calculating value&lt;/strong&gt;. Here it is just a &lt;code&gt;setTimeout&lt;/code&gt;, but it could be anything. So after 1000 milliseconds, our fake &lt;code&gt;getData&lt;/code&gt; gives us a response and &lt;strong&gt;resumes a generator with the value of response&lt;/strong&gt;. The next &lt;code&gt;yield getData(20)&lt;/code&gt; is processed in a similar way. What we get here is &lt;strong&gt;synchronously looking asynchronous code&lt;/strong&gt;. Our generator now is able to pause itself and resume when the async value is calculated in the exact same manner as it did with synchronous values. That's a huge deal.&lt;/p&gt;

&lt;h2&gt;
  
  
  The magic key
&lt;/h2&gt;

&lt;p&gt;Because the generator employs this &lt;strong&gt;pause/resume&lt;/strong&gt; thing he is able to block itself and wait for some background process to finish and then resume with the value we were waiting for. Abstract yourself from implementation details because it will be hidden in a library most of the time. What matters is the code inside a generator itself. Compare that to what we have seen in code using Promises. Promises' flow control organizes callbacks vertically into a chain. Think about Callbacks and Thunks - they are nesting those same callbacks. Generators bring their own flow control as well. But the very special feature of this flow control is that it looks completely synchronous. The async and sync code are sitting next to each other on equal terms. Neither do we &lt;strong&gt;see any difference&lt;/strong&gt; nor do we &lt;strong&gt;have to think about organizing our async code&lt;/strong&gt; in a different fashion anymore. Asynchronicity itself now is an implementation detail that we do not care about. It is possible because &lt;strong&gt;Generators&lt;/strong&gt; introduced a syntactic way to hide the complexity of state machines, in our case, asynchronous state machine. You are also getting all of the benefits of synchronous code like error handling. You are able to handle errors in your async code, in the same manner, using try-catch blocks. Isn't that beautiful?&lt;/p&gt;

&lt;h2&gt;
  
  
  Purging the IOC
&lt;/h2&gt;

&lt;p&gt;As you look at this example more carefully, you might notice that there is one problem with this approach. Our getData function is &lt;strong&gt;taking control of executing our generator&lt;/strong&gt; which leads us to &lt;strong&gt;Inversion Of Control&lt;/strong&gt;. This function gets to call &lt;code&gt;.next&lt;/code&gt; method on our generator in an unexpected way and mess everything up and the current codebase has no solution to it. Guess what? We are not afraid of this previously terrifying problem anymore. We just need to recall which pattern has already solved this issue for us. We are going to mix Promises together with Generators! And for this union to happen, instead of &lt;strong&gt;yielding undefined&lt;/strong&gt; we have to &lt;strong&gt;yield a promsie&lt;/strong&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  The ultimate duo
&lt;/h2&gt;

&lt;p&gt;Let's imagine how we could make this work. We've already said that inside of our generator we need to yield a promise. But who will take care of resolving that promise? Well, that would be done by the code that &lt;strong&gt;drives the generator&lt;/strong&gt;, that calls &lt;code&gt;.next&lt;/code&gt;. And once it gets a promise it should do something to it, it will have to &lt;strong&gt;wait for a promise to resolve&lt;/strong&gt; &lt;strong&gt;and resume a generator&lt;/strong&gt;. We are in need of an additional abstraction that will do it for us and most likely this will be provided by a framework, or library, or JavaScript itself. It is unlikely to be a practical thing to do - reinventing the wheel each time you want to work with promisified generators. But for educational purposes, we will figure out one ourselves and study it. &lt;/p&gt;

&lt;h2&gt;
  
  
  Building our Promises Generator runner
&lt;/h2&gt;

&lt;p&gt;I am going to provide you an implementation of such &lt;strong&gt;generator runner&lt;/strong&gt;. Obviously, it lacks some of the features that are absolutely required if you want to use it in production, such as proper handling, but it covers our needs and demonstrates the concept perfectly while keeping things rather simple.&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="nx"&gt;runner&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;generatorFunction&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;iterator&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;generatorFunction&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

  &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;nextStep&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;resolvedValue&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="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;value&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;nextIteratorValue&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;done&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;iterator&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;next&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;resolvedValue&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;done&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;nextIteratorValue&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;nextIteratorValue&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;then&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;nextStep&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="nb"&gt;Promise&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;resolve&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nx"&gt;then&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;nextStep&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 runner takes a generator function and produces an iterator as usual. Then it returns a resolved Promise and in &lt;code&gt;.then&lt;/code&gt; method we are passing our worker function &lt;code&gt;nextStep&lt;/code&gt;. It does a whole job of getting the next iterator value and checking if the generator is done. If not, we are assuming that the result of the &lt;code&gt;.next&lt;/code&gt; call was a Promise. So we are returning a new Promise ourselves by &lt;strong&gt;waiting for the iterator value Promise to resolve and passing the value to our working function&lt;/strong&gt;. The worker does the job of passing the result value to the iterator if it needs one and repeating its job until the generator is done. Nothing really complicated.&lt;/p&gt;

&lt;h2&gt;
  
  
  Working with our Generator Runner
&lt;/h2&gt;

&lt;p&gt;We are going to further modify our &lt;code&gt;sumIncrementedNumbers&lt;/code&gt; example to incorporate our new runner and take a look how we consume a promisified generator.&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="nx"&gt;getData&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;return&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nb"&gt;Promise&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;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;setTimeout&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nx"&gt;resolve&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="mi"&gt;1000&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="o"&gt;*&lt;/span&gt; &lt;span class="nx"&gt;sumIncrementedNumbersAsync&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;x&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;yield&lt;/span&gt; &lt;span class="nx"&gt;getData&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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;y&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;yield&lt;/span&gt; &lt;span class="nx"&gt;getData&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;20&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="nx"&gt;runner&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;sumIncrementedNumbersAsync&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;then&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;value&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="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;// After ~2000ms prints 32&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Everything here should already be familiar to you. Since our runner eventually results into a Promise, from the outside world perspective our wrapped generator is nothing more than just another Promise. We have managed to solve &lt;strong&gt;non-local, non-sequential reasoning&lt;/strong&gt; problems using our Generators to make async code look like synchronous one. We have brought Promises to do the dirty job of solving &lt;strong&gt;the Inversion Of Control&lt;/strong&gt; issue and created our simple &lt;strong&gt;Promises Generator runner&lt;/strong&gt;. Finally, we ended up with a clean interface of a Promise as a result and all of the Promises' benefits apply to our wrapped generator. That's why the Generators are so powerful. They completely change the way you write your asynchronous code. They finally provide you the ability to write a code that is intuitive for our brains and does not contradict the way we think.&lt;/p&gt;

&lt;h2&gt;
  
  
  Async/await ?
&lt;/h2&gt;

&lt;p&gt;In fact, this pattern proved itself so useful that in 2017 ECMAScript rolled out its very own implementation of async generators by introducing &lt;strong&gt;async/await&lt;/strong&gt; keywords. Don't let it fool you, because this feature is completely generator based and the concept is exactly the same. The difference is that now it is a first-class citizen in our language with proper syntax support and we are not required to use any helper libraries to do this job anymore. But there are some caveats with how &lt;strong&gt;async/await&lt;/strong&gt; works right now.&lt;/p&gt;

&lt;h2&gt;
  
  
  Pure generators vs async/await
&lt;/h2&gt;

&lt;p&gt;How would you cancel an async function and stop it from further execution? The thing is that there is no way to do so. Currently &lt;strong&gt;async/await&lt;/strong&gt; just returns a Promise. That's cool and all, but the ability to cancel is too crucial to ignore. And current implementation just does not give you enough tools for finer control of execution. I am not the one to judge their design decisions but my point is that the API could be further improved to, for example, return both a promise and a &lt;strong&gt;cancel&lt;/strong&gt; function. At the end of the day, we are working with generators that implement a &lt;strong&gt;pull&lt;/strong&gt; interface. We are in control of how to &lt;strong&gt;consume an iterator&lt;/strong&gt;. You could easily imagine how we could just stop consuming it in our runner if we would receive a cancel signal. To prove the point we can introduce a simple change to implement a very primitive cancel mechanism. And you could imagine somebody making a more sophisticated and error-proof variant with a rollback strategy.&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="nx"&gt;runner&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;generatorFunction&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;isCancelled&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;false&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;iterator&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;generatorFunction&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

  &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;nextStep&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;resolvedValue&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="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;value&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;nextIteratorValue&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;done&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;iterator&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;next&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;resolvedValue&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;done&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;nextIteratorValue&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;isCancelled&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="nb"&gt;Promise&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;resolve&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;nextIteratorValue&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;then&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;nextStep&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="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;cancel&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;isCancelled&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;promise&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;Promise&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;resolve&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nx"&gt;then&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;nextStep&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;This illustrates my point above. We are returning an object both with &lt;strong&gt;the Promise&lt;/strong&gt; and &lt;strong&gt;cancel&lt;/strong&gt; method. The cancel method just toggles a flag variable that is contained via closure. Pretty neat and opens a lot of possibilities for further enhancements.&lt;/p&gt;

&lt;h2&gt;
  
  
  Outro
&lt;/h2&gt;

&lt;p&gt;That was a lot of stuff to learn and discuss this time. But the topic itself is not the easy one and does not let you spend just 5 minutes of reading to get a grasp on it. I don't expect any of you to become generator experts by just completing this article, but I am pretty sure that I've given you a good start that will push you to further explore the topic yourself. With generators seems like we've answered each of our questions about async programming. We've solved Inversion of Control, we now are able to write synchronous looking asynchronous code, and looks like we've combined the best features from all of the previous patterns. But, as it often happens in Software Engineering, there is often more than one possible answer to the same problem. From this point, the next patterns we see will just offer you brand other ways of solving problems and each of them might be more or less suitable for your case. It's up to you as an engineer to make a final call. It will be completely fine if you quit at this point of the series because for most of us this could be enough to know about asynchronous programming in JavaScript for now. But if you decide to stick with me, we are going to take a look at some of the advanced patterns like &lt;strong&gt;CSP&lt;/strong&gt; and &lt;strong&gt;Observables&lt;/strong&gt;. We will surely have a talk about one of them next time. Thank you for the long read!&lt;/p&gt;

&lt;h2&gt;
  
  
  Credits
&lt;/h2&gt;

&lt;p&gt;Big thanks to &lt;strong&gt;Kyle Simpson&lt;/strong&gt; and his materials. I was particularly inspired by his &lt;a href="https://frontendmasters.com/courses/rethinking-async-js/"&gt;Asynchronous JavaScript&lt;/a&gt; course and it pushed me to deep dive into these topics a lot harder than I would have done normally. &lt;/p&gt;

</description>
      <category>javascript</category>
      <category>programming</category>
      <category>webdev</category>
      <category>patterns</category>
    </item>
    <item>
      <title>The saga of async JavaScript: Promises</title>
      <dc:creator>Roman Sarder</dc:creator>
      <pubDate>Fri, 17 Sep 2021 15:49:11 +0000</pubDate>
      <link>https://dev.to/romansarder/the-saga-of-async-javascript-promises-2n3i</link>
      <guid>https://dev.to/romansarder/the-saga-of-async-javascript-promises-2n3i</guid>
      <description>&lt;h2&gt;
  
  
  Intro
&lt;/h2&gt;

&lt;p&gt;We have been learning async JavaScript patterns in a way that it should now make sense why &lt;a href="https://dev.to/romansarder/the-saga-of-async-javascript-callbacks-13nk"&gt;Callbacks&lt;/a&gt; often might not be a sufficient solution to our day to day problems and how they helped &lt;a href="https://dev.to/romansarder/the-saga-of-async-javascript-thunks-4i03"&gt;Thunks&lt;/a&gt; to evolve into a powerful, lightweight tool. Although it didn't solve &lt;strong&gt;trust issues&lt;/strong&gt; and &lt;strong&gt;Inversion of Control&lt;/strong&gt; problem, the lessons we have learnt eventually resulted into a birth of a next pattern - &lt;strong&gt;Promises&lt;/strong&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Explaining the approach
&lt;/h2&gt;

&lt;p&gt;Armed with conceptual understanding and knowledge about innovations and drawbacks of Thunks we are now ready to take a look at what Promises can offer to us. We are not going to deep dive into Promise API and overwhelm ourselves with those fancy methods and properties right away. In the end of the day the particular method names and design solutions might differ between implementations, but the essential core idea will always stay the same. We are going to tackle the concept first and see how current JavaScript expresses it in terms of API.&lt;/p&gt;

&lt;h2&gt;
  
  
  Placeholder
&lt;/h2&gt;

&lt;p&gt;What would be a good real world example of Promises? It appears to be a rather simple thing to explain. Let's imagine ourselves coming to a restaurant. Most of us like burgers of some kind, don't we? So you come and order one. What do you usually get in return? The receipt with order number. Eventually you are going to exchange your receipt for the burger when an order is ready but until then you can safely think and start reasoning about it as if it was already in your hands. The receipt became a &lt;strong&gt;placeholder&lt;/strong&gt; for a &lt;strong&gt;future burger&lt;/strong&gt;. Promises are much like that. For some value that will be fulfilled in the future, you are given a placeholder - a &lt;strong&gt;Promise&lt;/strong&gt; - which later can be "exchanged" for a real value.&lt;/p&gt;

&lt;h2&gt;
  
  
  Inversion of Control: Round Three
&lt;/h2&gt;

&lt;p&gt;It appears that both Thunks and Promises are following the similar philosophy - they provide you a &lt;strong&gt;something&lt;/strong&gt; which you can work with until the real value shows up. But we had a problem of &lt;strong&gt;Inversion of Control&lt;/strong&gt; with Thunks because they were using callbacks under the hood. We passed a function and hoped for the best. How could you "uninvert" the Inversion Of Control? What if we would be in control of executing the code which will run after the value is ready? Let's reсall a dumb example that we invented to illustrate how serious this problem can get:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;fancyAsyncFunctionFromLibrary&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;chargeCreditCard&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;h2&gt;
  
  
  Pseudocode to the rescue
&lt;/h2&gt;

&lt;p&gt;We are not going to use current Promise API to help ourselves to solve this issue yet. Imagine that you don't have Promises invented at all. Flex you brain cells and try to think of a way to resolve the Inversion Of Control problem in this code using pseudocode. How would we modify an example above in order to get in control of executing our callbacks. Thankfully, there are plenty of patterns in programming that can inspire you. What about &lt;strong&gt;Event Emitters&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;futureValuePlaceholder&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;fancyAsyncFunctionFromLibrary&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

&lt;span class="nx"&gt;futureValuePlaceholder&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;on&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;complete&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;chargeCreditCard&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We made ourselves a &lt;code&gt;fancyAsyncFunctionFromLibrary&lt;/code&gt; which now returns an event emitter. Given the knowledge of what events you can get, we can attach our callbacks however we want. In this example, we run our callback once something is completed in that function so we could charge a credit card. We could subscribe to an error event in the same fashion. Or we could decide to not do so. We could even imagine ourselves detaching our listener once a complete event fired. There are plenty of things that we can do using this model. The pseudocode we've written basically says: "Give me an object which fires different events, and I will decide what events I will subscribe to and how I will run my functions in response to them". And the interesting part, it is not looking that different than Promises we use everyday. Instead of &lt;code&gt;on&lt;/code&gt; method we have &lt;code&gt;then&lt;/code&gt;, which actually knows what event it should subscribe your callback to. Despite the fact that callbacks are still the essential part of our code, we were able to regain the control of the execution and run our functions on our terms using a nice and clean API. To summarise, the other way you can think of Promises is that &lt;strong&gt;they are much like Event Emitters&lt;/strong&gt;. But to solve the Inversion of Control disaster, we need something more than an API. There is a missing part.&lt;/p&gt;

&lt;h2&gt;
  
  
  Trust enforcing
&lt;/h2&gt;

&lt;p&gt;We still might be in doubt of how our callbacks will be run. There is a list with a decent amount of concerns about callbacks that is menacingly standing right next to our newborn event emitter. We desperately need trust to be introduced to eliminate those. The Promises would not be of much use if they didn't incorporate &lt;strong&gt;trust enforcing mechanisms&lt;/strong&gt;. Thankfully, when you are using Promises in current JavaScript, JavaScript itself ensures that:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;promises are immutable&lt;/li&gt;
&lt;li&gt;errors are not swallowed&lt;/li&gt;
&lt;li&gt;the promise will either succeed or throw an error&lt;/li&gt;
&lt;li&gt;it only resolves once&lt;/li&gt;
&lt;li&gt;no actions at a distance&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Pretty neat, huh? Having a well defined and strict behavior, we are no longer questioning ourselves about the way our callbacks are run. The &lt;strong&gt;immutable&lt;/strong&gt; part is also very important. JavaScript makes sure that when you pass your Promise to a third party code, there is no way that it will somehow get mutated or changed in any way. You simply cannot affect both promise's state and a value inside. No &lt;strong&gt;action at a distance&lt;/strong&gt;. Also our code is now safe from being called multiple times and we are always getting an error no matter what. Even if you are not handling that error explicitly in your Promise, it will bubble up as &lt;code&gt;Unhandled Promise rejection&lt;/code&gt; and you will not miss compiler yelling at you.&lt;/p&gt;

&lt;h2&gt;
  
  
  Show us Promises, sir
&lt;/h2&gt;

&lt;p&gt;Let's take our pseudocode that we wrote before and use Promises this time:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;fancyAsyncFunctionFromLibraryWithPromise&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="nb"&gt;Promise&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;resolve&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="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;fancyAsyncFunctionFromLibrary&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="p"&gt;})&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nx"&gt;fancyAsyncFunctionFromLibraryWithPromise&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;then&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;chargeCreditCard&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;handleError&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Our &lt;code&gt;fancyAsyncFunctionFromLibrary&lt;/code&gt; now returns a Promise that we have created ourselves. You are getting a &lt;strong&gt;first-class&lt;/strong&gt; object which you can pass around much like any other value. When constructing a Promise, you pass it a callback which expects two arguments: a &lt;code&gt;resolve&lt;/code&gt; and &lt;code&gt;reject&lt;/code&gt; functions. These are your tools to switch the state of promise to either a fullfilled state or rejected. We call a &lt;code&gt;then&lt;/code&gt; method to attach a callback which will be executed once Promise is fullfilled, in other words resolve function got called inside of our Promise. That callback receives a value of Promise if there is any. On the opposite side there is a catch method for error handling which works in a similar way. We have to handle only two possible cases and we have two corresponding methods that we need. The code itself reads much like human language: "Do something that takes time, then pass it to this function, but if something went wrong, catch the error and pass it to this function".&lt;/p&gt;

&lt;h2&gt;
  
  
  Flow control
&lt;/h2&gt;

&lt;p&gt;Let's try ourselves in writing some sequence of operations using promises and see how they look like in a bit more common example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;readFileOnePromise&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;then&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;fileContents&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="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;first file&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;fileContents&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;readFileTwoPromise&lt;/span&gt;
    &lt;span class="p"&gt;})&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;then&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;fileContents&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="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;second file&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;fileContents&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;readFileThreePromise&lt;/span&gt;
    &lt;span class="p"&gt;})&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;then&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;fileContents&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="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;third file&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;fileContents&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;This time temporal dependencies between operations don't have to result into more nesting and they all stay on the same level throughout the program. The notable feature which makes working with Promises much easier is &lt;strong&gt;chaining&lt;/strong&gt;. &lt;/p&gt;

&lt;h2&gt;
  
  
  Chaining
&lt;/h2&gt;

&lt;p&gt;Chaining is some sort of syntax that allows you to do multiple object method calls without intermediate variables. This is achieved by each method returning the object. Inside &lt;code&gt;then&lt;/code&gt; method's callback you can either return a Promise or a value. In case you returned a Promise, the next &lt;code&gt;then&lt;/code&gt; will not fire its callback until this Promise is resolved. You can handle both in the same way and this results in a time independent value wrapper much like Thunks. But oftentimes it is only API which makes people use Promises and think that they are a silver bullet in a world of async programming. Remember that the important part about Promises is not their API, but their idea and concept which at some time in the past innovated the way you work with asynchronous code in your programs. It is about their ability to finally solve Inversion of Control issue while keeping the advantages of being a container around the data which you can pass around and a placeholder for a future value.&lt;/p&gt;

&lt;h2&gt;
  
  
  Callbacks.. again?
&lt;/h2&gt;

&lt;p&gt;Yes, we still have callbacks. Actually, if you look at Promises carefully, you would see that they might look like &lt;strong&gt;callback managers&lt;/strong&gt;! And that's the third and final way I was able to think of Promises. They use callbacks for the same well known tasks - running code once something is completed, and in addition they bring in the trust that we needed. The important point in Promises is that they &lt;strong&gt;reduce the gap between async and sync code even further&lt;/strong&gt;. There are two very important things about synchronous functions:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;they return value&lt;/li&gt;
&lt;li&gt;they throw errors&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Promises composition
&lt;/h2&gt;

&lt;p&gt;More importantly, if we are talking about &lt;strong&gt;function composition&lt;/strong&gt;, if any of functions in a composition throws an error, that error bypasses all other composition layers and goes all the way up so the client code would be able to catch it. In case of Callbacks, returning value was impossible since they just were not ready at a moment of call. Similarly, you could not throw errors because there was nobody to catch them and with callbacks you would need to manually propagate those errors. Promises do an important job of bringing back those things into asynchronous world by saying that each function should return a promise and guaranteeing that an error will bubble up. If written correctly, those then/catch blocks &lt;strong&gt;compose in a similar manner as their synchronous counterparts&lt;/strong&gt; by having fulfillments creating a compositional chain with rejections being able to interrupt it at any stage that is only handled by someone who declares that he is ready to handle it. &lt;/p&gt;

&lt;h2&gt;
  
  
  A bit of functional programming
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;then&lt;/code&gt; method instead of being viewed as "callback attaching mechanism" could be viewed as "trasformation application". It basically allows us to apply transformation on value inside a promise and create a new one which will be passed down the chain. From this point of view, Promises are very similar to &lt;strong&gt;Monads&lt;/strong&gt; with their ability to chain and apply functions on underlying values. Although the current JavaScript API for Promsies itself is not as 100% pure as functional programmers would desire, the monadic nature of promises is quite obvious.&lt;/p&gt;

&lt;h2&gt;
  
  
  More of fancy API
&lt;/h2&gt;

&lt;p&gt;Promises come with plenty of additional methods to improve your flow control out of the box. &lt;code&gt;Promise.all&lt;/code&gt; will take an array of promises and return a new promise which resolves once all promises are resolved. &lt;code&gt;Promise.any&lt;/code&gt; is similar in a way that it expects an array of promises, but will return a promise which resolves once at least one promise is resolved. If there are no resolved promises, the result promise gets rejected. I will not go through each and every method on Promise object in JavaScript but you probably get the idea. Promises also provide you some useful abstractions which help you to orchestrate not one, but a group of promises in a more complex scenarios. Once you start discovering the documentation, you will find yourself inventing those abstractions on the fly. Not all of them are currently implemented, but nobody stops you from using third party promise libraries. You can even create one yourself!&lt;/p&gt;

&lt;h2&gt;
  
  
  Downsides
&lt;/h2&gt;

&lt;p&gt;I noticed that there are some articles about Promises that focus on &lt;strong&gt;API misusage&lt;/strong&gt; when talking about the downsides. There are also many of them which don't talk about any problems with Promises at all. There are a couple of things left that Promises didn't manage to solve or provide. My attitude towards most of the issues with Promises could be described as "Ah, but this and that thing would also be handy, altough it would not make sense in this pattern". Having our main enemy - &lt;strong&gt;Inversion of Control&lt;/strong&gt; - defeated, we are now only looking for more features to make our toolset complete. And you will see that things described below are screaming for another pattern to be created to use alongside Promises. So take these points as "nice to haves" instead of "need to fix".&lt;/p&gt;

&lt;h2&gt;
  
  
  Still out of main flow
&lt;/h2&gt;

&lt;p&gt;This could be a debatable point. While Promises reduce the number of nested callbacks you are working with, they are not removing them entirely. Using standard Promises, there is no way for our synchronous code to "wait" for promise. Consider this example:&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;func&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;promise&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;somePromiseBasedFunction&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

    &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;promiseValue&lt;/span&gt; &lt;span class="o"&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="nx"&gt;then&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;function&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;// I can access the value here, but there's&lt;/span&gt;
        &lt;span class="c1"&gt;// no way for me to get it up in the main&lt;/span&gt;
        &lt;span class="c1"&gt;// scope and have `func` return its value&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;finalValue&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;someOtherFunction&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;promiseValue&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;finalValue&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;Altough the purpose of promises is to not block your program, oftentimes we really need this kind of mechanism to be available. This would close the gap between sync and async code even more. Techically, this got solved in later versions of JavaScript with &lt;strong&gt;async/await&lt;/strong&gt;, but those are based on generators and are subject to a separate article.&lt;/p&gt;

&lt;h2&gt;
  
  
  Not cancellable
&lt;/h2&gt;

&lt;p&gt;This one also contradicts the ideology behind promises. No doubt, an ability to cancel a promise with an outgoing AJAX request would be super great, but that would also mean that Promises are no longer immutable and suddenly we are now vulnerable to an "action at distance" problem.&lt;/p&gt;

&lt;h2&gt;
  
  
  Missing abstractions
&lt;/h2&gt;

&lt;p&gt;Just a "nice to have" thing which often makes you create those methods from scratch or use third party library as an alternative. A list of available Promise abstractions implemented currently can feel a bit limiting in some cases. For example, imagine yourself chaining 10 &lt;code&gt;then&lt;/code&gt; calls and trying to remember that each time you need to return a Promise to make a composition work. It can easily become annoying and prone to errors when dealing with a long chain. How about &lt;code&gt;sequence&lt;/code&gt; method which would accept a variable number of functions and do that for you? It will automatically chain those function calls and ensure that each of them will return whatever the next one needs to make it work. As I said, one could come up with at least a couple of useful methods that are not presented in current API and it would be great to have them implemented in a language itself.&lt;/p&gt;

&lt;h2&gt;
  
  
  Outro
&lt;/h2&gt;

&lt;p&gt;It has been a great journey. We finally got rid of Inversion of Control problem and by accumulating our knowledge and experience across the patterns we've managed to deep dive into Promises and properly understand why they became a thing. At this point, the creation of Promises should be a pretty obvious thing for you because this pattern is mostly a correction of mistakes from previous ones. They are currently an important and powerful tool in our arsenal and they will stay like this for a while. But the picture of ideal async programmer's life is incomplete and there are missing features and concepts which are to be implemented. Similar to callbacks, Promises themselves will serve as a foundation for a next pattern which will enhance their capabilities to provide us even better experience. As we go further, topics will keep getting more and more challenging, so I am very excited to tell you about other patterns. In next article we will talk about &lt;a href="https://dev.to/romansarder/the-saga-of-async-javascript-generators-5dhi"&gt;&lt;strong&gt;Async Generators&lt;/strong&gt;&lt;/a&gt; and see how async/await feature works under the hood.&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>programming</category>
      <category>webdev</category>
      <category>architecture</category>
    </item>
    <item>
      <title>The saga of async JavaScript: Thunks</title>
      <dc:creator>Roman Sarder</dc:creator>
      <pubDate>Sun, 05 Sep 2021 16:51:35 +0000</pubDate>
      <link>https://dev.to/romansarder/the-saga-of-async-javascript-thunks-4i03</link>
      <guid>https://dev.to/romansarder/the-saga-of-async-javascript-thunks-4i03</guid>
      <description>&lt;h2&gt;
  
  
  Intro
&lt;/h2&gt;

&lt;p&gt;Last time we talked about &lt;a href="https://dev.to/romansarder/the-saga-of-async-javascript-callbacks-13nk"&gt;Callbacks&lt;/a&gt; - a pattern that is deceptively easy to understand. The concept which we will discuss today is a next step of evolution and naturally extends the callbacks' capabilities. It also brings us an interesting solution for async programming and most importantly - it shifts our mindset and forces us to look at things from the different perspective. This time I want to provide you a comprehensive explanation on what are &lt;strong&gt;thunks&lt;/strong&gt; and how it can help to organize our code better.&lt;/p&gt;

&lt;h2&gt;
  
  
  What the hell is that?
&lt;/h2&gt;

&lt;p&gt;For real though, I wish I knew why somebody came out with this name. But jokes aside, thunks are the thing that at some point made me wondering how I had got so far with JavaScript without even knowing how powerful it can be. From a synchronous perspective, thunk is essentially a &lt;strong&gt;function&lt;/strong&gt; that is ready to give you some value back and requires no additional input. As simple as that. Many of you working with React probably know an awesome and plain simple library called &lt;a href="https://github.com/reduxjs/redux-thunk"&gt;redux-thunk&lt;/a&gt; which as name suggests is based on thunks. But more on that later. For now let's take a look at a simple example of a synchronous thunk:&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="nx"&gt;superCalculation&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="mi"&gt;9999&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;9999&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;outFirstThunk&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kd"&gt;function&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;superCalculation&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;sum&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;thunk&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="c1"&gt;// 19998&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here we have a thunk called &lt;code&gt;ourFirstThunk&lt;/code&gt; which value is a &lt;strong&gt;function&lt;/strong&gt; and when it gets called it will always return us the same value - the result of out &lt;code&gt;superCalculation&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  The part we care about
&lt;/h2&gt;

&lt;p&gt;The important part is that this thunk has become a wrapper around some particular state. In this case it is a result of a potentially expensive operation. Imagine yourself shooting a beautiful moment on vintage film. The film itself is your thunk and the captured moment is the wrapped state. We can now pass this "film" around our app and when we want to extract that state, we simply "develop the film" by calling the thunk and get the value back. Instead of working with the state itself, we are passing a &lt;strong&gt;representation&lt;/strong&gt; of the value. Pattern allows us to conveniently hide the details of underlying computation and provides a common interface. We also managed to &lt;strong&gt;delay&lt;/strong&gt; the calculation until we really need it and it is possible now to inject this operation into different parts of our code. This is what is also called &lt;strong&gt;lazy thunk&lt;/strong&gt;.  &lt;/p&gt;

&lt;h2&gt;
  
  
  Going async
&lt;/h2&gt;

&lt;p&gt;Things start to become quite intriguing when you are thinking about async applications. So how would you possibly describe an async thunk? For the most part it is the same. It's a function which doesn't need any arguments to make its job &lt;strong&gt;except&lt;/strong&gt; for a callback. Interestingly enough despite all of its flaws, callback pattern has managed to find its use here. The standard synchronous implementation does not take time factor into account and we already saw that callbacks are pretty capable of handling "future value processing". Why not use it here as well? Let's extend our previous example to an asynchronous thunk:&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="nx"&gt;superCalculationAsync&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="nx"&gt;setTimeout&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="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="mi"&gt;9999&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;9999&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="mi"&gt;1000&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;thunk&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kd"&gt;function&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="nx"&gt;superCalculationAsync&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="nx"&gt;thunk&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="nx"&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;// 19998&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We now have an &lt;code&gt;superCalculationAsync&lt;/code&gt; function which fakes an asynchronous behaviour by using &lt;code&gt;setTimeout&lt;/code&gt; utility. We then create a &lt;code&gt;thunk&lt;/code&gt; which is a function accepting a callback. This callback is passed to &lt;code&gt;superCalculationAsync&lt;/code&gt; function to handle the result of the operation. The overall concept stays the same, except for callback coming into play to help us handle things. Still we end up with a handy container which we can use anywhere in our app as long as we pass the callback.&lt;/p&gt;

&lt;h2&gt;
  
  
  Lazy vs Eager
&lt;/h2&gt;

&lt;p&gt;We managed to convert our synchronous thunk into an asynchronous one. You will notice that our &lt;code&gt;superCalculationAsync&lt;/code&gt; itself is not executed right away. This is a &lt;strong&gt;lazy thunk&lt;/strong&gt;. Until the callback is provided, no calculations will fire. Let's try to toy with this example a little bit more and think of the way to rewrite it to &lt;strong&gt;eager thunk&lt;/strong&gt; - the one which will try to run calculations in advance and attempt to give you result back immediately.&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;thunk&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;thunkResult&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;handleResult&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nx"&gt;superCalculationAsync&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;function&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="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;handleResult&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="nx"&gt;handleResult&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;thunkResult&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;// result is not ready&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="nx"&gt;thunkResult&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;result&lt;/span&gt; &lt;span class="c1"&gt;// result is ready&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="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;runThunk&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;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;thunkResult&lt;/span&gt;&lt;span class="p"&gt;)&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="nx"&gt;thunkResult&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;// result is ready&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="nx"&gt;handleResult&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;callback&lt;/span&gt; &lt;span class="c1"&gt;// result is not ready&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;While developing an eager thunk you stumble upon two possible cases that you need to handle. The first case is when thunk is called &lt;strong&gt;after&lt;/strong&gt; the inner operation is completed and we can safely return the result. This is the easy part and it is no different to what we have been doing so far. The second case is something to think about - the thunk is called, but the operation is still going. We have to bridge those two branches of our program somehow. The provided solution is by no means the most performant and elegant one but it gets work done. Here we ended up with two &lt;code&gt;if&lt;/code&gt; statements that mirror each other. We call the user's callback with a result of an underlying computation if it is already done. If not, we are injecting the provided callback directly. Client's code will not even know that the thunk might take time to complete.&lt;/p&gt;

&lt;h2&gt;
  
  
  Power comes with abstraction
&lt;/h2&gt;

&lt;p&gt;Here is the point - we could rewrite our synchronous example with a callback and then treat both an async and sync thunk uniformly. By doing that we are effectively freeing ourselves from dealing with a time factor in our code by having this kind of normalization. We don't have to know or care about the how a value is delivered to us. The first time we call our thunk and pass a callback it might do significant work to get an expected response. It could be an AJAX request, a CPU intensive task or any other crazy stuff which can take a while. But the second time we call it, it might decide to memoize the return value and give it to us right away. A client code using our thunks doesn't need to have any concerns on internal implementation as long as it has the way to work with both synchronous and asynchronous code in the same manner. This is a big step forward. We have produced a wrapper around data that is time independent. And we know that time might be the most complex thing to manage in our applications.&lt;/p&gt;

&lt;h2&gt;
  
  
  Real world example
&lt;/h2&gt;

&lt;p&gt;I have already mentioned &lt;strong&gt;redux-thunk&lt;/strong&gt; - a library that is recommended to use for handling side effects in redux app according by redux maintainers themselves. It provides us a middleware which expects a thunk or a simple action object and handles them accordingly. It is so dead simple, that main function which creates a middleware is just 9 lines of 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;function&lt;/span&gt; &lt;span class="nx"&gt;createThunkMiddleware&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;extraArgument&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="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;dispatch&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;getState&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;next&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;action&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;typeof&lt;/span&gt; &lt;span class="nx"&gt;action&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;function&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="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;action&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;dispatch&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;getState&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;extraArgument&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;next&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;action&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;The code is pretty straightforward and most likely doesn't need any explanation at all. This is conceptually the same thunk we were talking about above. The only difference comes with a few extra arguments that are passed into our thunk - &lt;code&gt;dispatch&lt;/code&gt; and &lt;code&gt;getState&lt;/code&gt; with &lt;code&gt;dispatch&lt;/code&gt; fulfilling a role of a callback.&lt;/p&gt;

&lt;h2&gt;
  
  
  Simplicity
&lt;/h2&gt;

&lt;p&gt;The great thing about thunks is that this is just a pure JavaScript code. No libraries or frameworks involved. By adopting a different way of thinking, we managed to eliminate a confusing and difficult to handle thing called time. Let it sink for a moment. The mental overhead is gone and replaced with a common interface which represents our value. As a bonus, we are capable of reusing these representations across our code without any problems. But there is a revelation to be made.&lt;/p&gt;

&lt;h2&gt;
  
  
  The dreaded Inversion of Control issue
&lt;/h2&gt;

&lt;p&gt;I will make this statement right away - thunks were not created to address Inversion Of Control issue. This is not a silver bullet in the world of async programming. In the example above, &lt;strong&gt;redux-thunk&lt;/strong&gt; library has no way to ensure that their &lt;code&gt;dispatch&lt;/code&gt; function will be called appropriately. The same is true for our examples. What thunks are effectively doing is that they are laying a foundation for &lt;strong&gt;Promises&lt;/strong&gt;. If you are familiar with promises, and I am pretty sure most of you are, you can notice that thunks are essentially Promises without a fancy API. Yes, we are getting benefits of uniform treatment, reusability and a nice wrapper which encapsulates the details of our computations, but Inversion Of Control issue is still to be solved. Also, because thunks are still using callbacks under the hood, you could easily end up with something that is very similar to &lt;strong&gt;Callback Hell&lt;/strong&gt;. If we try to express several operations that have temporal dependencies between each other, that would become clear. Let's assume that we have a &lt;code&gt;makeThunk&lt;/code&gt; utility which accepts a function and a list of parameters which are passed to wrapped to it. For the sake of simplicity I will not provide any implementation details on it, you can find plenty of those on the internet.&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;readFirst&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;makeThunk&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;readFile&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;first file&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;readSecond&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;makeThunk&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;readFile&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;second file&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;readThird&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;makeThunk&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;readFile&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;third file&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="nx"&gt;readFirst&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;firstFileContents&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="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;first file contents&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;firstFileContents&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nx"&gt;readSecond&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;secondFileContents&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="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;second file contents&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;secondFileContents&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="nx"&gt;readThird&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;thirdFileContents&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="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;third file contents&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;thirdFileContents&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;We first precreate three thunks for later use. It is important to understand that &lt;code&gt;readFile&lt;/code&gt; is not executed until we pass the callback. On the next lines, we nest thunks executions to get the right order of operations. The rule &lt;strong&gt;temporal dependency === nesting&lt;/strong&gt; holds true here as well. &lt;/p&gt;

&lt;h2&gt;
  
  
  Outro
&lt;/h2&gt;

&lt;p&gt;Thunks went a long way to improve our JavaScript code. This pattern brings couple of crucial benefits comparing to callbacks and still manages to be lightweight and simple. And the best part is that it is all possible with just the functions' manipulations. As we saw in redux-thunk library example, thunks make handling side effects in our Redux a childsplay in just 9 lines of code. After some practice you could imagine that capabilities of this pattern extend far beyond the scope of just React &amp;amp; Redux apps. Thunks ideologically precede the &lt;strong&gt;Promise&lt;/strong&gt; pattern and these two are much similar. Although thunks didn't manage to solve the Inversion Of Control issue, we will see how the conceptual core of this pattern with an addition of new API finally succeeds. Thank you for a read, keep your eyes on updates and next time we will talk about &lt;a href="https://dev.to/romansarder/the-saga-of-async-javascript-promises-2n3i"&gt;Promises&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>architecture</category>
      <category>webdev</category>
      <category>programming</category>
    </item>
    <item>
      <title>The saga of async JavaScript: Callbacks</title>
      <dc:creator>Roman Sarder</dc:creator>
      <pubDate>Tue, 31 Aug 2021 16:28:38 +0000</pubDate>
      <link>https://dev.to/romansarder/the-saga-of-async-javascript-callbacks-13nk</link>
      <guid>https://dev.to/romansarder/the-saga-of-async-javascript-callbacks-13nk</guid>
      <description>&lt;h2&gt;
  
  
  Intro
&lt;/h2&gt;

&lt;p&gt;The heart of modern JavaScript application lies in its interactivity. Buttons are being clicked, mouse is moving while you are dragging your image to upload a new avatar, AJAX requests is going out to get your favourite feed - all of these can happen while that cute cat video is preloading along with its comments' thread. Thanks to JavaScript being asynchronous, we can leverage those events while keeping the app responsive. Without knowing how to orchestrate those temporal dependencies well, the complexity in our code will quickly get out of hand.&lt;/p&gt;

&lt;h2&gt;
  
  
  So what's next?
&lt;/h2&gt;

&lt;p&gt;In this series of articles we will try to explore different patterns that help us write asynchronous JavaScript. Most modern libraries and frameworks use at least one of them. And most developers have no idea about their strengths and weaknesses. We will take a look at why those patterns exist. We're gonna explore which problems do they solve, and which they don't. In the end of the series, hopefully, you are going to be familiar enough to know when to use each one of them and reason about this decision. Take your seats, gentlemen, and today we will have a tough talk about &lt;strong&gt;callbacks&lt;/strong&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Callbacks? We already know those
&lt;/h2&gt;

&lt;p&gt;I get it. It will be a decent challenge to find a JS developer who doesn't have at least a rough idea of what callbacks are. We all know how they look like. You pass the function as an argument and it is called after a certain action is completed. We are going to have a little practice with callbacks before going deeper into their flaws. Consider this simple expression of a callback in an async fashion.&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="nx"&gt;mortalCombatGreet&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="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Choose your destiny&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;setTimeout&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;mortalCombatGreet&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1000&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  How is that working?
&lt;/h2&gt;

&lt;p&gt;Functions in JavaScript are first-class citizens which basically means that they can do everything others can do. You can assign them to variables, pass as arguments, return from the functions. In the example above we pass our callback function to a built-in API, but it could be any other API or library. The description of this code would be: "create a timer with a callback, execute a callback in 1000ms". When dealing with callbacks, there is some code which will execute immediately, and some code which will be run later. We essentially divide our program into two parts - the first part is everything outside of a callback including &lt;code&gt;setTimeout&lt;/code&gt; call, and the other one is our callback itself. There is a clear notion of "now" and "later".&lt;/p&gt;

&lt;h2&gt;
  
  
  More callbacks to the God of callbacks
&lt;/h2&gt;

&lt;p&gt;Now let's consider an example that is a bit more sophisticated. We will try to read three files in a sequential order using callbacks. Assume that &lt;code&gt;readFile&lt;/code&gt; function is some function that takes time to complete.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;readFile&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;first file&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;firstFileContents&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="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;firstFileContents&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="nx"&gt;readFile&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;second file&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;secondFileContents&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="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;secondFileContents&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

        &lt;span class="nx"&gt;readFile&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;third file&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;thirdFileContents&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="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;thirdFileContents&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;Here we tried to express a temporal dependency using callbacks. Pretty straightforward and common async operation to use. We can clearly see that a second file read need to &lt;strong&gt;wait&lt;/strong&gt; for a first read to finish. Same relationship exists between third and second reads.&lt;/p&gt;

&lt;h2&gt;
  
  
  Temporal dependency === nesting?
&lt;/h2&gt;

&lt;p&gt;You could notice that an expression of each single temporal dependency is achieved through nesting callbacks inside of each other. And you could also imagine this going really big and crazy in some complex parts of application logic. This is  often referred to as &lt;strong&gt;Callback Hell&lt;/strong&gt; or &lt;strong&gt;Pyramid Of Doom&lt;/strong&gt; in Javascript community (did you really think I attached that pyramid image by accident?). When it comes to this concept, people mostly complain about nesting and indentation. But is it all about how the code looks? I could immediately start proving you, that code formatting is not the fundamental problem of the 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="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;readFirst&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;cb&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;readFile&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;first file&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;fileContents&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="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;fileContents&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
       &lt;span class="nx"&gt;cb&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="nx"&gt;readSecond&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;cb&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;readFile&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;second file&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;fileContents&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="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;fileContents&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
       &lt;span class="nx"&gt;cb&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="nx"&gt;readThird&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;readFile&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;third file&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;fileContents&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="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;fileContents&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;})&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nx"&gt;readFirst&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;readSecond&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;readThird&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;This code definitely doesn't obviously suffer from identation and nesting problems, does it? This is what is often called as continuation passing style. We could go on with refactoring and eventually come up with something that would not look like a callback hell to an average javascript developer at all. This is where the most serious problem lies. This is where our understanding needs to be redefined, because this code is as susceptible to callback hell as previous one.&lt;/p&gt;

&lt;h2&gt;
  
  
  Inversion of control
&lt;/h2&gt;

&lt;p&gt;Notable feature of callbacks is that the part of our code is executed by a third party. We can't exactly know &lt;strong&gt;when&lt;/strong&gt; and &lt;strong&gt;how&lt;/strong&gt; our code will be executed. When we loose control on our code and pass it to someone else, the Inversion Of Control happens. There are many definitions of the Inversion of Control term on the internet, but for our case that's pretty much it.  &lt;/p&gt;

&lt;h2&gt;
  
  
  Trust issue
&lt;/h2&gt;

&lt;p&gt;In our first example we passed our code to &lt;code&gt;setTimeout&lt;/code&gt; utility. There is nothing wrong with it, right? We all use timers! Timer API is a well known and established feature. Nobody is thinking to themselves "oh, wait, maybe it will not execute my code right in time, or it will not even execute it at all". We can &lt;strong&gt;trust&lt;/strong&gt; it. And that's the main point. What if we pass our callback to some external library that is not a part of standard API? What if, for example, we rely on something else to execute the code which charges our client's credit card?&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;fancyAsyncFunctionFromLibrary&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
     &lt;span class="nx"&gt;chargeCreditCard&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;When you are passing callback you are trusting that it will be called:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;not too many times&lt;/li&gt;
&lt;li&gt;not too few times&lt;/li&gt;
&lt;li&gt;not too early&lt;/li&gt;
&lt;li&gt;not too late&lt;/li&gt;
&lt;li&gt;with no lost context&lt;/li&gt;
&lt;li&gt;with correct arguments&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;What happens if this trust falls apart? Can you really cover all of those cases with workarounds in all of the places where you use callbacks? I would assert to you, that if you have callbacks in your application and you don't have those cases covered, then your app potentially has as many bugs as there are callbacks in it.&lt;/p&gt;

&lt;h2&gt;
  
  
  Going natural
&lt;/h2&gt;

&lt;p&gt;Without diving deep into the science, we can safely say that our brain is essentially single threaded. We can think about only one single thing at a time at our highest level of cognition. We also like to think about stuff in a sequential fashion. Take a look at how you are planning your day. You allocate your time for a &lt;strong&gt;single&lt;/strong&gt; task and complete each of them &lt;strong&gt;sequentially&lt;/strong&gt; one by one: take shower, have a breakfast, make a call to the boss, participate in a meeting, etc. But it often doesn't play that nice, does it? Usually, at least a couple of times, you will get interrupted. Your mom calls while you are on a meeting, delivery guy rings a door when you are trying to wrap your head around a bug. Thankfully, when this happens, you are not going like: "ok, that's awful, I am going to my bed and start tomorrow from scratch". From this perspective, our brain is a lot like a JavaScript engine. It can be interrupted with an event, choose to respond to it and then continue running.&lt;/p&gt;

&lt;h2&gt;
  
  
  Where the bugs happen
&lt;/h2&gt;

&lt;p&gt;If that's how our brains work and how we handle tasks, we are most likely to code in the same way... naturally. But language engines, as well as JavaScript, often don't work the way that is immediately obvious to us. Every time you are not thinking about the code in a different way than a compiler, there is a potential bug in your program. Thankfully, we can both train ourselves to think more like a compiler and invent new patterns and syntax that both fit our mindsets and computer needs. That's why it is extremely important to understand how all of those patterns, frameworks and libraries work internally. And it is not enough to just know the API and a general definition.&lt;/p&gt;

&lt;h2&gt;
  
  
  Reasoning about callbacks
&lt;/h2&gt;

&lt;p&gt;Remember me saying that the only way to handle temporal dependency using callbacks is through nesting? Consider the next pseudo code which will express how we would like to, at least in my opinion, reason about async operations:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;start someBigOperation1
do stuff
pause

start someBigOperation2
do stuff
pause

resume someBigOperation1
do more stuff
pause

resume someBigOperation2
do more stuff
finish

resume someBigOperation1
do more stuff
finish
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Would be great to have this sort of syntax to handle async operations in Javascript, huh? We are doing one step at a time, and our brain linearly progresses through the code. Doesn't look like callbacks at all... but what if it did?&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;start someBigOperation1
do stuff
pause
    resume someBigOperation1
    do more stuff
    pause
        resume someBigOperation1
        do more stuff
        finish

start someBigOperation2
do stuff
pause
    resume someBigOperation2
    do more stuff
    finish
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Whether you are doing it with function expressions or with function calls, that doesn't matter. The code is not looking sequential anymore, you can't instantly figure out the order of operations and you are forced to jump all over the code to get the idea. The async flows in our apps can become really complex, and I doubt that there is a developer in your team who understands all of them from start to end. You can understand step one, two and three, but it quickly becomes a thing beyond our capacity as soon as it goes like this: "start step one, two and three, and as soon as step two is finished, cancel step three and retry step two, then start step four". God bless you if those steps are callbacks jumping around the files in your projects. This is the case when your brain is fundamentally unable to reason about the program anymore. Callbacks force us to express in a fashion that contradicts the way our brains are used to plan things. Callbacks alone don't have right tools to let us write sequentially looking async code. Seems like we need a better pattern.&lt;/p&gt;

&lt;h2&gt;
  
  
  What doesn't fix the problems
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Multiple callbacks
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;readFile&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;fileContents&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="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Success! &lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;fileContents&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="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;error&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="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Error! &lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;There is way now for the utility to notify us about an error using a second callback. Looks good. But guess what? Now we are trusting the utility to execute &lt;strong&gt;two&lt;/strong&gt; callbacks properly and basically you end up with 2x the number of potential bugs that you need to cover in your code. Ouch!&lt;/p&gt;

&lt;h3&gt;
  
  
  Error first style of callbacks
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;readFile&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;fileContents&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;error&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="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Error! &lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Success! &lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;fileContents&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;Two callbacks are too crazy, so let's get back to just one. We are going to reserve the first parameter for an error. It definitely removes the concerns about calling two callbacks, but what happens if utility messes up the order of arguments? What if it calls callback twice - once with error, and then without it? What if it calls the callback both with error and success arguments? The same trust issues arise with couple of new ones. Still doesn't look like a solution at all.&lt;/p&gt;

&lt;h2&gt;
  
  
  Outro
&lt;/h2&gt;

&lt;p&gt;You should now have a pretty good understanding of callbacks and be able to articulate about their drawbacks. It is clear that callbacks alone will not help you to solve each and every problem in your async code. Hopefully, next time when you hear about Callback Hell, you will be confident about what it truly means. It is about design limitations which can't be solved no matter how much you refactor your code. The Ideal Pattern should provide us an ability to write async code that looks like a synchronous one. That sounds fantastic, but it should be possible, right? There are still plenty of approaches to take a look at and in the next article we will talk about &lt;a href="https://dev.to/romansarder/the-saga-of-async-javascript-thunks-4i03"&gt;Thunks&lt;/a&gt; and see how they make asynchronous programming much easier.&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>webdev</category>
      <category>programming</category>
    </item>
  </channel>
</rss>
