“This article has participated in the call for good writing activities, click to view: the back end, the big front end double track submission, 20,000 yuan prize pool waiting for you to challenge!”

The original intention of this series of articles is to “let each front-end engineer master the high frequency knowledge, for the work of power”. This is the front end of the number 32 cut, I hope friends pay attention to the public number “kite”, armed with knowledge of their minds.

9.1 Task Classification

9.1.1 Generalized classification

In a broad sense, tasks can be divided into two types: synchronous and asynchronous tasks.

  1. Synchronization task

A queued task on the main thread can be executed only after the previous task is completed.

  1. Asynchronous tasks

A task that does not enter the main thread but enters the Task queue will enter the main thread only when the task queue notifies the main process that an asynchronous task is ready to execute. (Note: Asynchronous tasks address performance issues.)

To expand: Why do asynchronous tasks exist?

Because JS is single-threaded, if only synchronous tasks, all tasks are executed in a single thread, so only one task can be executed at a time, while other tasks are in a waiting state, resulting in a long wait for the next task. Asynchronous tasks can solve this problem well.

9.1.2 Accurate classification

In addition to the broad classification of synchronous and asynchronous tasks, there are more precise classifications: macro tasks and micro tasks.

  1. Macro task

Macro tasks mainly refer to the tasks in the task queue, including the following types:

(1) Overall script code

(2) the setTimeout

(3) the setInterval

(4) setImmediate (Exclusive to Node)

(5) the I/O

  1. Micro tasks

Microtask is a function that needs to be executed asynchronously. The execution time is after the execution of the main function and before the completion of the current macro task. It mainly includes the following categories: (Note: microtask solves the real-time problem)

(1) Process. nextTick(Node only)

Add callback to the queue at the next point in time;

(2) MutationObserver

A MutationObserver is used to monitor a DOM node, and when the DOM node changes, a DOM change log is generated.

(3) Promises and other techniques developed based on promises (note: microtasks are also created when Prommise. Resolve () or promise.reject () is called).

To expand: Why microtasks? What problem does it solve?

If there are no microtasks, performing all operations in the same priority order will cause the real-time problems of some high-priority tasks, which is why microtasks appear. By putting tasks with high real-time requirements into the microtask queue, the real-time requirements of high-priority tasks can be guaranteed.

9.2 Event Cycle Process

JS uses a single-threaded “Event Loop” to handle the execution of multiple tasks. The following explains the whole process from two perspectives.

9.2.1 Synchronous and asynchronous Angles

From the point of view of synchronous and asynchronous tasks, the entire event loop flow can be divided into the following steps:

  1. Synchronous and asynchronous tasks enter different execution sites respectively. Synchronous tasks enter the main thread, and asynchronous tasks enter the Event Table and register functions.
  2. When the specified Event is complete, the Event Table moves the function to the Event Queue.
  3. If the execution of the main thread is empty, the Event Queue will read the corresponding function and enter the main thread for execution.
  4. This process is repeated over and over again, known as the Event Loop.

Note: this figure is from the network

9.2.2 Macro and micro task perspectives

From the perspective of macro and micro tasks, the whole event loop mechanism can be divided into the following steps:

  1. Obtain a macro task to start execution, in the execution of the first to create a microtask queue, when the encounter microtask will be put into the microtask queue;
  2. Then obtain all the microtasks in the microtask queue and execute them successively (note: the microtasks generated during the execution of the microtask will be placed at the end of the microtask queue and completed in this cycle)
  3. Execute the process in a loop.

9.3 the actual combat

The core of the event loop is the need to distinguish the task types, as long as the task types are divided and executed in sequence, the following code to illustrate the entire output.

console.log('start');
​
setTimeout(function() {
    console.log('setTimeout1');
    const promise2 = new Promise((resolve, reject) => {
        console.log('promise2');
        resolve();
    });
​
    promise2.then(() => {
        console.log('then2');
        const promise3 = new Promise(resolve => {
            console.log('promise3');
            resolve();
        });
        promise3.then(() => {
            console.log('then3');
        });
    });
}, 1000);
​
setTimeout(function() {
    console.log('setTimeout2');
    const promise4 = new Promise((resolve, reject) => {
        console.log('promise4');
        resolve();
    });
​
    promise4.then(() => {
        console.log('then4');
    });
}, 1000);
const promise1 = new Promise(resolve => {
    console.log('promise1');
    resolve();
});
​
promise1.then(() => {
    console.log('then1');
});
​
console.log('end');
Copy the code

Once you understand the whole event loop, you can easily come up with the answer as follows:

start
promise1
end
then1
setTimeout1
promise2
then2
promise3
then3
setTimeout2
promise4
then4
Copy the code

1. If you think this article is good, share and like it so that more people can see it

2. Pay attention to the public number of kite, and the number of the Lord together to kill the front hundred