This is the first day of my participation in Gwen Challenge

The queue is widely used in daily life, such as queuing up for dinner in the canteen, drumming flowers and so on. At the same time, it is also widely used in the front end, such as Event loop, JS asynchronous task queue.

So, queue structure is a must-learn for the front end. In the following article, we will explain the use of queues in the front end.

What is a queue

A queue is a linear first-in, first-out (FIFO) table. It only allows insertion at one end of the table and deletion of elements at the other.

2. Application scenarios

  • A fifO scenario is required.
  • For example: canteen queue for meals, train station queue for tickets, JS asynchronous task queue, calculate the number of recent requests…… .

Front end and queue: event loop and task queue

1, the event loop

Event loop, also known as event loop or event polling. Since JS is run in a single thread and asynchron needs to be implemented based on callback, event loop is the implementation principle of asynchronous callback.

2. How to execute JS

The execution of JS in a program follows the following rules:

  • From front to back, line by line
  • If a line of execution fails, stop the execution of the following code
  • Execute synchronous code first, and then execute asynchronous code

Let’s take a look at an example:

console.log('Hi');

setTimeout(function cb1(){
    console.log('cb1'); //cb1 is the callback function
}, 5000);

console.log('Bye');

// Print order:
//Hi
//Bye
//cb1
Copy the code

As you can see from the above example, JS executes the synchronous code first, so it prints Hi and Bye first, and then executes the asynchronous code to print CB1.

Using this code as an example, let’s begin the process of event loop.

3. Event Loop procedure

For the above code, the execution process is shown below.

From the figure above, you can analyze the path of this code. First console.log(‘Hi’) is the synchronization code that executes directly and prints the Hi. The timer setTimeout is asynchronous code, so at this point the browser will hand it over to the Web APIs to handle the matter, so put it in the Web APIs first, then continue with console.log(‘Bye’), Console.log (‘Bye’) is synchronized code that is executed in the Call Stack, printing Bye.

At this point, everything in the Call Stack is finished, and when the Call Stack is empty, the browser will go to the task queue to find the next task, and the task queue will go to the Web API to find the task, follow the first in, first out principle, and find the timer, The timer contains the callback function CB1, so the callback function CB1 is passed to the task queue. At this time, the Web API is also empty, and the tasks in the task queue are passed to the Call Stack for execution. Finally, CB1 is printed.

DOM events and Event loops

Let’s start with two pieces of code.

console.log('Hi');

setTimeout(function cb1(){
    console.log('cb1'); //cb 即 callback
}, 5000);

console.log('Bye');

/* Output: Hi Bye cb1 */
Copy the code
<button id = "btn1">submit</button>

<script>   
    console.log('Hi');

    document.getElementById('btn1').click(function(e){
        console.log('button clicked');
    });

    console.log('Bye');
</script>/* Result: Hi Bye button clicked */Copy the code

In the above two pieces of code, the first paragraph is about the setTimeout event loop, and the second paragraph is about the DOM event loop. DOM events are asynchronous operations, so why is the output still at the end?

Actually, DOM events are not asynchronous, but they do use callbacks, based on the Event Loop, so when we click, the DOM event is triggered and printed.

To summarize the differences between DOM events and Event loops:

  • JSIs single-threaded;
  • Asynchronous (setTimeoutajaxEtc.) using callbacks, based onevent loop
  • DOMEvents are not asynchronous, but also use callbacks, based onevent loop

5. Event Loop summary

After the initial understanding of event loop, let’s make a summary:

Summary event Loop procedure 1

  • Synchronized code, line by lineCall StackImplementation;
  • In case of asynchrony, the system “records” and waits for an opportunity (timing or network request).
  • When the time is right, move toCallback Queue.

Summary event Loop procedure 2

  • ifCall StackIs empty (that is, synchronization code has finished), thenevent LoopGet to work;
  • Wheel office to findCallback QueueIf yes, move toCall StackImplementation;
  • Then continue to search (like a perpetual motion machine, constantly search).

Macro and micro tasks

1, the quotes

Let’s start with a piece of code.

console.log(100);
setTimeout(() = > {
    console.log(200);
});
Promise.resolve().then(() = > {
    console.log(300);
});
console.log(400);
/** * Print result: * 100 * 400 * 300 * 200 */
Copy the code

In the above code, the first and second prints are based on synchronization. We all know that 100 and 400 are to be printed, but the third and fourth prints should theoretically be printed in 200 and 300 order. Why 300 and 200? This involves a question of macro and micro tasks. Macro and micro tasks will be explained next.

2. Macro and micro tasks

(1) Commonly used macro tasks and micro tasks

The name of the Examples (commonly used)
Macro task Script, setTimeout, setInterval, setImmediate, Ajax, DOM events, I/O, UI Rendering
Micro tasks Process.nexttick (), Promise, async/await

The setTimeout and setInterval mentioned above are task sources, and what really enters the task queue is the task they distribute.

Note: micro tasks are executed earlier than macro tasks!!

(2) Priority of macro tasks and micro tasks

priority

  • SetTimeout = setInterval A queue
  • setTimeout > setImmediate
  • process.nextTick > Promise

(3) Code to achieve micro tasks and macro tasks

for(const macroTask of macroTaskQueue){
    handleMacroTask();
    for(const microTask ofmicroTaskQueue){ handleMicroTask(); }}Copy the code

(4) Event loop and DOM rendering

As mentioned in topic 3, Point 4 above, DOM events are based on callbacks and are based on the Event loop mechanism. At what point in the program’s execution do DOM events render?

Look at this code again.

<button id = "btn1"> submit < / button ><script>   
    console.log('Hi');

    document.getElementById('btn1').click(function(e){
        console.log('button clicked');
    });

    console.log('Bye');
</script>

/* Result: Hi Bye button clicked */
Copy the code

As can be seen from the above figure, when the program call stack is idle, the program will try to perform DOM rendering first, and then trigger the Event Loop mechanism. So, in the above code, the program prints the synchronization codes Hi and Bye, waits for the synchronization code to finish printing, looks for DOM events, performs rendering, and finally fires the Event loop.

To summarize the relationship between Event loop and DOM rendering:

  • At the time of execution, JS is single threaded and shares a thread with DOM rendering.

  • So JS execution should leave some time for DOM rendering.

  • If the Call Stack is cleared each time (that is, each poll ends), the synchronization task is complete.

  • The application will always give the DOM a chance to re-render if its structure changes;

  • Then the next Event Loop is triggered.

(5) The relationship between microtasks, macro tasks and DOM rendering

Let’s look at the relationship between microtasks, macro tasks, and DOM rendering:

  • Macro task: DOMApply colours to a drawingafterTrigger, such assetTimeout
  • Micro tasks: DOMApply colours to a drawingbeforeTrigger, such asPromise

Let us first demonstrate the phenomenon and then investigate the principle.

1

const $p1 = $('

A paragraph of text

'
); const $p2 = $('

A paragraph of text

'
); const $p3 = $('

A paragraph of text

'
); $('#container') .append($p1) .append($p2) .append($p3); // Microtasks: trigger before DOM rendering Promise.resolve().then(() = > { console.log('length', $('#container').children().length); alert('Promise then'); //(alert blocks JS execution and DOM rendering for easy viewing) }); Copy the code

In the code above, the browser looks like this.

As you can see in the figure, the micro-task promise is triggered before the DOM renders, so the promise is printed before the corresponding text of the DOM is displayed.

2

const $p1 = $('

A paragraph of text

'
); const $p2 = $('

A paragraph of text

'
); const $p3 = $('

A paragraph of text

'
); $('#container') .append($p1) .append($p2) .append($p3); // Macro task: triggered after DOM rendering setTimeout(() = > { console.log('length1', $('#container').children().length); alert('SetTimeout'); //(alert blocks JS execution and DOM rendering for easy viewing) }); Copy the code

In the code above, the browser looks like this.

As can be seen from the figure, the setTimeout pop-up box appears only when the corresponding text of DOM has been displayed, so the macro task setTimeout is triggered after DOM rendering (i.e., DOM rendering and display end).

At this point, back to what we were talking about.

  • Macro task: DOMApply colours to a drawingafterTrigger, such assetTimeout
  • Micro tasks: DOMApply colours to a drawingbeforeTrigger, such asPromise

From the above demonstration, you should understand the relationship between microtasks, macro tasks and DOM. In the first demo, the microtask Promise was fired before the DOM was rendered, so the microtasks were fired before the DOM was rendered. In the second demo, the macro task setTimeout triggers the alert only after the text display ends, so the microtasks are triggered only after DOM rendering.

(6) Why are microtasks earlier

Now that we understand how microtasks and macro tasks relate to DOM, we have a general idea why microtasks are older than macro tasks. At the Eventloop level, why do microtasks happen earlier than macro tasks and start firing before DOM renders?

Let me draw a picture of it.

The micro task executes without passing through the Web APIs, instead placing it in a micro Task Queue. And the micro task is ES6 ‘syntax specified, macro task is specified by the browser, so it will be earlier than macro task.

Now that we have covered the Event loop and its related macro and micro tasks, let’s use another diagram to summarize the actual execution order.

It can be concluded from the above graph that:

In the first step, the program programs the contents of the Call Stack first. When the Call Stack is empty, the program performs the current microtask.

In the second step, the program finds the task in the microtask queue and executes the microtask.

The third step, after the completion of the micro-task, try to perform DOM rendering;

Step 4, after DOM rendering, trigger event loop to execute macro task.

Write at the end

Queues are used very, very often in the front end. Almost all asynchronous functions we write involve event loops in their execution. And in the front-end interview, they are often asked what event loop, event loop or event polling is, and many interviewees are easy to lose in this content. Eventloop, microtasks, and macro tasks have gained a deeper understanding.

So much for the use of queues in the front end! If you do not understand or wrong place is also welcome to comment on the comment area or private letter I exchange ~

Pay attention to the public number Monday laboratory, do not regularly share learning dry goods ~

Be sure to like and follow this article if it’s useful to you