Illustrated JS: JavaScript asynchronous behaviour
Tags: codenewbie, javascript, beginners, learning
Published: 2020-08-06 10:51:00


_While learning JavaScript and programming in general, I find it useful to take notes and create some analogies to understand the concepts. Here I will share some of my notes about the asynchronous behaviour of JavaScript and the fact it’s single threaded. Feel free to correct me if I understood something wrong._

JavaScript has only one thread running for each process. I think about it as a kitchen where only one baker is in charge for the process of baking a cake with chocolate icing.

The baker is the CPU and they would have to execute one  subprocess at a time: baking the cake and preparing the icing. After that, the same person would also have to cover the cake with the icing.

<figure>
  <img src="https://dev-to-uploads.s3.amazonaws.com/i/memzx8zzkngbqkfcys4f.jpg" alt="Drawing of a baker executing all steps for the cake process"/>
  <figcaption>Fig.1 - One baker (CPU) doing one subprocess at a time (single thread)</figcaption>
</figure>

If it was multithreaded we could have only one CPU executing different subprocesses at the same time (baker with more arms).

<figure>
  <img src="https://dev-to-uploads.s3.amazonaws.com/i/fcjx9fe2gmeuwow92e13.jpg" alt="Drawing of a baker with multiple arms doing different tasks" width="40%"/>
  <figcaption>Fig.2 - One baker (CPU) doing multiple subprocesses at the same time (multithreads)</figcaption>
</figure>

Or we could have more CPUs (bakers) working in different subprocesses: cake preparation, icing preparation and cake covering. 

<figure>
  <img src="https://dev-to-uploads.s3.amazonaws.com/i/fjk2qjqf9c3tulnvli0w.jpg" alt="Drawing of 3 bakers executing 1 step for the cake process each"/>
  <figcaption>Fig.3 - Three bakers executing subprocess concurrently</figcaption>
</figure>

But in that case, the third subprocess (covering the cake) would need resources from the other two. So it would be necessary to add synchronisation to those actions, but let’s not focus on that right now. 

Although multithreading maximises the CPU time, it’s a little bit more complex because it's harder to handle the concurrency, and the results are unpredictable.

<figure>
  <img src="https://dev-to-uploads.s3.amazonaws.com/i/788u3lyctw4bfn4sy5kp.jpg" alt="Drawing of the oven on fire, burnt icing and the third baker without cake or icing"/>
  <figcaption>Fig.4 - Unpredictable results in multithreading (absolutely exaggerated) </figcaption>
</figure>

It's also important to mention that JavaScript is single threaded but it’s not synchronous. It means it doesn't need to completely finish one task before starting another one. 

If that was the case, my baker would have to keep waiting for the oven to finish baking the cake, for instance, before being able to start the icing preparation.

<figure>
  <img src="https://dev-to-uploads.s3.amazonaws.com/i/3p5kxk9fzfhlk893owfd.jpg" alt="Drawing of a baker staring at the oven waiting for it to finish baking the cake" width="40%"/>
  <figcaption>Fig.5 - The baker is waiting for a slow action (baking the cake) to return before starting the icing preparation</figcaption>
</figure>

In fact, JavaScript has some resources that allows us to make it asynchronous, and in our cake example, the baker is able to start making the icing while they wait for the cake to be baked.

<figure>
  <img src="https://dev-to-uploads.s3.amazonaws.com/i/2o9vaibjkn35gkzy061w.jpg" alt="Drawing of a baker starting the icing preparation while the oven bakes the cake" width="60%"/>
  <figcaption>Fig.6 - Starting the icing preparation without waiting for the cake preparation action to be finished</figcaption>
</figure>

But let’s say our baker finishes the icing and the cake isn’t baked yet. Without the cake, they would not be able to move to the next step, which is covering the cake with the icing. 

<figure>
  <img src="https://dev-to-uploads.s3.amazonaws.com/i/7y0ukl7c7mtxeb2s2662.jpg" alt="Drawing of a baker with the icing but no cake" width="40%"/>
  <figcaption>Fig.7 - The icing is finished before the cake, but the baker can't do the next task (covering the cake)</figcaption>
</figure>

Many operations in JavaScript depend on external responses like interactions with APIs or network communications and we don’t know for sure when we are going to receive the result of those actions.

That's why we need to make sure that those dependent actions won’t be executed until we have access to the responses they need. For that, we can use promises and I'll talk about that on my next article. 

<figure>
  <img src="https://dev-to-uploads.s3.amazonaws.com/i/2fc5vrvq7encvz8d6kk9.jpg" alt="Drawing of an oven with a cake baking inside and the subtitle: promise of a cake" width="40%"/>
  <figcaption>Fig.8 - A promise object wrapping an asynchronous action (baking the cake)</figcaption>
</figure>