Introduction:

JavaScript is a single-threaded language (in layman’s terms, one thing at a time). Asynchronous operations are placed in an event loop queue, waiting for the main execution stack to execute. There is no dedicated asynchronous execution thread.

How do we explain that we can only do one thing at a time?

Ask questions

<! -- omitted CSS section --><body>
<section>
  <div class="process" id="process-one"></div>
  <div class="process" id="process-two"></div>
  <button onclick="start()" style="margin-top: 20px">start</button>
</section>
</body>
<script>
function handle(dom) {
  let i = 0;
  (function run() {
    dom.innerHTML = i
    dom.style.width = i + The '%'
    if (++i <= 100) {
      setTimeout(run, 50()})}})let processOne = document.getElementById('process-one')
let processTwo = document.getElementById('process-two')
function start(){
  handle(processOne)
  handle(processTwo)
}
</script>
Copy the code

You can see that when you click the Start button, both progress bars load simultaneously, right?

Let’s explain this phenomenon perfectly through the following study.

Noun explanation

Before we explain this list of terms let’s look at a picture

It can be roughly divided into four modules:

Execute the Stack

The main thread code is preferentially executed. When all the main thread codes are executed, the tasks in the microtask queue are preferentially taken from the task queue. When all the microtask queues are executed, the tasks in the macro task queue are preferentially taken from the macro task queue

Note: if a microtask is generated during the execution of the macro task, the microtask code will be executed first

MacroTasks

Mainly include:

  • Script (whole code)
  • setTimeout.
  • setInterval.
  • setImmediate.
  • I/O.
  • ui rendering

In the new standard it is called Task

Microtasks

Mainly include:

  • process.nextTick(NodeJs)
  • Promise
  • MutationObserver(New HTML5 features)

It’s called Jobs in the new standard

Time module

SetTimeout and setInterval are used to read seconds

Code execution

So much for the conceptual stuff, let’s explain the whole event polling mechanism with code and images

Write the output order based on the code in the stack below

Write down the specific process below:

  1. Execute code ① to print 1
  2. Execute code ②, willsetTimeoutInsert the Time module to start reading seconds (the current Time is 0, in modern browsers, at least 4ms, that is, even if the writing is 0, there will be 4ms of reading seconds).
  3. Execute code ③, the Promise is the microtask, and put it into the microtask queue.
  4. Execute code ④ and print 4
  5. At this point, all synchronous tasks are completed, and asynchronous tasks are started. First, the micro task callback function of the first micro task is put into the execution stack to continue execution
  6. Execute the callback function of code block ③ to print print 3
  7. At this point, the synchronization task is all executed, and it continues to fetch from the microtask. At this point, the microtask queue is empty, and the time loop mechanism will fetch from the macro task and put the callback function of code block ② into the execution stack
  8. Execute the callback function of the code block ② taken from the macro task to print print 2

Final result: 1, 4, 3, 2

So what is the Event Loop mechanism? The mechanism by which the above process is actually executed repeatedly is called Event Loop.

Knowing the above process, congratulations, the whole event polling mechanism is that simple

Now let’s look at some of the things that we need to remember

Timing module running time

setTimeout(function(){
  // How many seconds will it take for the program to arrive here
}, 1000)
JSON.parse('./index.json')  // Suppose the parsing takes 5 seconds
Copy the code

Here are some simple explanations: SetTimeout will start reading seconds after it is put into the Time module, so it is not read seconds after JSON parsing 5, but before JSON parsing. Therefore, after JSON execution is completed, setTimeout reading seconds will already be counted. The callback function is placed in the macro task queue and will be executed immediately

Macro tasks contain microtasks

Let’s look at the macro task with a microtask in it. After looking at the example above, try writing the following output:

console.log(1)

setTimeout(() = > {
  console.log(2)
  Promise.resolve().then(() = > {
    console.log(3)})})new Promise((resolve, reject) = > {
  console.log(4)
  resolve(5)
}).then((data) = > {
  console.log(data);
  return 6;
}).then((data) = >{
  console.log(data)
})

setTimeout(() = > {
  console.log(7);
})

console.log(8);
Copy the code

See which of the following is your answer (A/B)

A: 1,4,8,5,6,2,3,7

B: 1,4,8,5,6,2,7,3

If it’s neither A nor B, then congratulations, go back to the top of the article and read it again

The only thing that might confuse you here is the order of 3 and 7

In simple terms, during the execution of the macro task, a microtask is generated. Should we continue to process the subsequent macro task or process the microtask first?

Want to understand this, actually very simple, here to remember a word: all asynchronous task in the implementation process, from the asynchronous task queue callback function got the task to perform in the stack, after performing the task stack code, at this time will continue in accordance with the previous way, from micro tasks first, and then taken from the macro task

In the code above, the setTimeout callback function generates a microtask when it is put into the execution stack. After the execution stack is completed, the event loop mechanism will first go to the microtask queue to get the task to execute according to the agreed steps.

So the correct answer is: A


After understanding the whole Event Loop, it is actually not difficult. Write down a simple summary to deepen the impression!