The following is an excerpt from the newest book that I have been working on "Asynchronous JavaScript". You can read it online for free at asyncjsbook.com

If you are new to async programming in JavaScript, you might be surprised with the result of the following piece of code:

setTimeout(function() {
  console.log('1');
}, 0);
console.log('2');

What do you think the output of the above code will be? You might be tempted to say 1 and then 2, but the correct answer is 2 and then 1. In th following sections we will dive into the asynchronous model used in JavaScript and explain why the above code prints 2 and then 1.

Synchronous vs Asynchronous

When you do your daily tasks it's highly likely that you do them asynchronously. Let's look at an analogy to illustrate the difference between the synchronous and asynchronous models of execution.

Imagine that you have three tasks to do in your daily chores list:

  1. Do laundry
  2. Do groceries
  3. Cook dinner

With a synchronous model, you have to finish each task before moving on to the next. That is, you have to finish laundry first before moving onto doing the groceries. If your laundry machine is broken, you cannot do the groceries. The same applies for the third task, you can only cook dinner if and only if you have completed the groceries (and laundry).

Now with an asynchronous model, you don't have to wait for each task to finish to move onto the next. You can start the washing machine and do the groceries while your clothes are being washed. By the time you come back from the grocery store, your clothes are washed. Now if you need to dry your clothes, you can put them in the dryer and cook dinner while your clothes are being dryed.

That's basically the main difference between the synchronous and asynchronous models of execution. In the synchronous model, you have to wait for each task to finish before moving onto the next. But in the asynchronous model you don't have to. You can schedule tasks in a way to effectively do more in less time and not wait if you don't have to. In the next section we will look at the event loop and learn how JavaScript deals with asynchronous tasks.

The Event Loop

Let's look at the snippet that we saw in the beginning of the chapter:

setTimeout(function() {
  console.log('1');
}, 0);
console.log('2');

When you call the setTimeout method, it will be pushed on what is called the message queue. After that, the console.log(2) will be called immediately. After console.log(2) is called the stack empty and JavaScript moves onto the queue and executes what's on the queue. The mechanism that manages this flow is called the event loop. The event loop is responsible for looking at what's on the stack and the queue and scheduling the execution in the right order. In the figure below there are three tasks on the stack to be executed. Once they are finished, two more tasks are picked up from the queue and placed on he stack to be executed:


Now that's an oversimplified version of the event loop. Obviously it's way more complicated than that, but in essence, the event loop is responsible for listening for tasks that can be executed in the near future.

There are a couple of higher level abstractions like promises and async/await that can help you write clean async code. I have been working on a book that explains each in detail. You can read the book online for free at asyncjsbook.com