preface

(The final combing is concise and is being gradually improved)

There are a lot of articles about js implementation on the web, so why write about this?

The reason is that there are two kinds of opinions about one of the mechanisms.

1. Controversial points

1. Thinks that the macro task contains all script code

So, my personal understanding is that macro tasks are callbacks generated by JavaScript and the host environment, and tasks that need to be handled by the host environment and are put into the callback queue are macro tasks.

Source: author: Reed links: https://juejin.cn/post/6844903814508773383 the Denver nuggets

For those who are not clear about the concept of host environment, let me briefly describe: host environment is a carrier of JS running, common browsers, Node.js and so on.

Let’s get down to business. In addition to generalized synchronous and asynchronous tasks, we have a more detailed definition of tasks:

  • Macro-task: includes the entire code script, setTimeout, and setInterval
  • Micro-task: Promise, process.nexttick

Source: author: ssssyoki links: https://juejin.cn/post/6844903512845860872 the Denver nuggets

This is what I agree with: macro tasks contain script main code blocks

2. Macro tasks do not contain all script code

First of all, macro tasks and micro tasks are defined as asynchronous JS statements. Console. log is obviously a synchronization statement. A JS file execution, should be the main execution stack to execute synchronous statements, encountered asynchronous statements, put into the task queue. After that, the microtask queue is executed, and then the macro task in the head is removed from the macro task queue to execute. During the execution, a new microtask queue is generated. This loop continues until the macro and micro tasks have all been executed. Eventloop author: love to eat oranges links: https://segmentfault.com/q/1010000023206213?utm_source=tag-newest source: segmentfault think no

Since code is not a task, console.log() is not a task, nor is it a macro task.

Promise. Then and MutationObserver are “micro-tasks”, but if you don’t have a clear loop of events, it’s easy for an interviewer to use these “micro-tasks” to cheat you out. A task is simply the entry point from which a block of code starts execution (specifically, the entry point to a function stack, but the concept of a stack is more complicated). In JS, in addition to “script whole code block”, all code block entry is “callback function”, callback function is registered to the event will not be executed immediately, but stored in a mysterious place, save to be executed can be counted as “task”, and then there are macro/micro tasks. “Overall script code block” special, lies in its entry is not a callback function, but we can imagine it comes in a stealth function, be registered as a callback function to an event in the (presumably it will trigger an event) after parsing is complete, then the stealth function becomes a task.

Source: author: madRain links: https://segmentfault.com/q/1010000023206213?utm_source=tag-newest segmentfault think no

The short answer is: asynchronous code distinguishes between macro and micro tasks

3. Blurred boundaries

Both micro tasks and macro tasks are asynchronous tasks, which belong to the same queue. The main differences lie in their execution sequence and the direction and value of Event Loop. So what’s the difference between them? . Macro tasks typically include script, setTimeout, setInterval, and setImmediate.

Microtasks: Native Promises (some implemented promises put then methods in macro tasks), process.nextTick, Object.observe(deprecated), MutationObserver. Source: author: qian zhang qianniuer links: https://juejin.cn/post/6844903638238756878 the Denver nuggets

Ii. (macro) mission no truth

A macro task is a task in the first place. Because ES6 introduced the Promise standard, and the browser implementation added a microtask concept, as a comparison is called macro tasks.

Paste the MDN document definition

A task is any JavaScript that is scheduled to be executed by a standard mechanism, such as program initialization, event-triggered callbacks, and so on. In addition to using events, you can also use setTimeout() or setInterval() to add tasks.

The difference between task queues and microtask queues is simple, but important:

  • When executing tasks from the task queue, each task in the queue is executed by the runtime at the beginning of each iteration of the new event loop. Tasks added to the queue at the beginning of each iteration will not be executed until the next iteration begins.
  • Every time a task exits and the execution context is empty, each microtask in the microtask queue is executed in turn. The difference is that it waits until the microtask queue is empty before stopping execution — even if a microtask joins in mid-stream. In other words, a microtask can add new microtasks to the queue and complete all of the microtasks before the next task starts and the current event loop ends.

This leads to the conclusion that the macro task contains the JS main code block.

From the difference, we can also clearly see the cyclic mechanism of JS events. The macro tasks added to the task queue after the start of each macro task iteration must wait until the execution of the next task iteration. Those added in the middle of the microtask will also finish before the end of the event cycle.

3. Knowledge points

Start with definitions, but skip the ones you’re familiar with to see the full relationship summary in the table of contents

Synchronous and asynchronous

The first thing to know is that JS is a single-threaded scripting language. // Although H5 proposes worker, it is also implemented on a single thread basis

Synchronization is the process of js tasks entering the task stack and waiting for the main thread to execute in sequence. Simply speaking, it is the process of JS code running from top to bottom. If there is an infinite loop in the middle of a synchronization task, then the browser may appear JS no response. That means you can’t execute further down.

However, when we read the local file data, or fetch the server interface data, the time is not determined, should the subsequent JS code wait? This can make the page look clunky and seriously affect the user experience. Instead of entering the main thread task stack, the event Table is first entered and the callback function is registered. Then the asynchronous event queue is entered in order and called after the main thread task stack finishes executing (the queue is first in first out, so it is called in the order in which the registration function is queued).

// It doesn’t matter if you are tired of reading the text

Macro and micro tasks

MacroTasks

The main block of code that enters the task stack to wait for the main thread to execute, including callbacks from asynchronous queues such as setTimeout() and setInterval (), which do not include callbacks from asynchronous queues such as promise.then.

Note that the macro task added from the asynchronous queue to the stack in the event loop is executed as the next event. Due to the GUI rendering thread mechanism, the page will be rendered after each event loop, as shown below:

First macro task complete → page rendering → first macro task complete (including the macro task added to the asynchronous queue when the last macro task event) → page rendering….

Common macro tasks are:

  • The main block of code
  • setTimeout
  • setInterval

Microtasks

Is the task to be executed in an asynchronous queue after the current macro task is executed and before the page is rendered.

Note that even if a new microtask is created during the execution of the current microtask, all the microtasks will be executed before the execution of the next macro task and before the end of the current event loop.

First macro task → first all micro tasks → page rendering → second macro task (including the macro tasks added to the asynchronous queue when the last macro task event) → Second all micro tasks → page rendering….

Common microtasks include:

  • process.nextTick ()
  • Promise
  • Object.observe

4. Complete relationship summary

1. The body code (all the script code at the start of the first event loop) enters the task execution stack as a macro task, but a series of decisions are made before the main thread executes.

2. Determine whether the current task is synchronous or asynchronous. The synchronous task is executed by the main thread in the task stack in advance and out order (local context first, then global context).

3. The asynchronous macro tasks are added to the asynchronous macro task Event Table (there are two types of asynchronous queues: macro task queue and micro task queue, and event Table is the same). The micro tasks are added to the micro task event Table, and after the callback function is registered, they are added to the corresponding queue again.

4. When the tasks of the main thread are completed, it will check whether there are tasks in the microtask queue, and execute them if there are, and so on, until it knows there are no tasks in the microtask queue.

5. After the microtask of the current event is completed, the next event will be executed, that is, the macro task in the macro task queue will be executed, and so on until there are no more tasks.

A little heart

Write not so good, where there is a problem please feel free to point out, or what you want to discuss can leave a message, if you can not go to see, click on the “core JS” once to understand the JS operation mechanism to see the big guy’s article. Just give it a thumbs up.

Thank you!

It will continue to be improved.