This article has participated in the good article call order activity, click to see: back end, big front end double track submission, 20,000 yuan prize pool for you to challenge!

The JS engine does not provide event loops

When we talk about event loops, we often say please talk about JS event loops. This often leads to the misconception that event loops are a feature of the JS language.

It’s not. To understand this, let’s first clarify these concepts.

Host environment, JS engine, rendering engine

The host environment consists of a JS engine and a rendering engine. The most common hosting environment is the one provided by the browser.

  • JS engine: Runs JavaScript code. The most famous is Chrome’s V8 engine.
  • Render engine: Typeset and display web pages. The most famous is the Webkit engine.

Note that the JS engine runs in the JS thread and the render engine runs in the render thread. The browser makes them mutually exclusive, so when one thread runs, the other thread hangs.

In addition to the browser, Node.js is also the primary hosting environment, which does not include the rendering engine. It also provides a slightly different time loop than the browser.

The host environment provides event loops

Since the JS engine does not provide event loops and, crucially, JS is a single-threaded language, browsers need a mechanism to enable JS to handle asynchronous tasks, hence the time loop mechanism.

Let’s list some browsers that have asynchronous tasks:

  • DOM events. Such as the mouse click generated callback.
  • Callback generated by the HTTP request.
  • SetInterval and setTimeout. Callback generated by the timer.

The resulting callbacks are then queued up for events. When the JS engine is idle, execute them in turn (but the timer must wait for them to run out of time before executing them).

Macro tasks and microtasks

All of these are macro tasks. It is the host that gives JS the ability to handle asynchrony. However, the macro task still has its drawbacks. After all, it is the API provided by the host and involves interacting with the JS engine, so the performance is definitely a little bit poor. At the same time, JS itself is also aware of its own shortcomings, a single threaded language, itself does not have the ability to deal with asynchronous.

Over time, the JS language itself supported asynchronous programming, and here came the Promise (aka microtasks)! For the JS language, it makes up for its own asynchronous capabilities and provides front-end developers with one more option to deal with asynchrony.

This is the nature of macro and micro tasks:

  • A macro task provided by the host.
  • Provided by the JS language itself, for microtasks.

The timing of their execution, then, makes perfect sense. In the process of JS code execution, some macro tasks and micro tasks are generated. After the current task is finished, execute all the microtasks that are ready, because they are inside the JS engine. Execute all of them first, then consider the interaction with the outside. When the microtask is done, all right, go to the host and see if there are any macro tasks I need to work on.

As shown in the figure below: The microtask queue is inside the JS engine, and the macro task queue is outside the JS engine. After executing all the microtasks, go outside and find a macro task to execute.

What else does an event loop do

In addition to the part for the JS engine, the event loop also has a part for the rendering engine.

As shown in the figure below, every time the event loops, it checks to see if it needs to be rendered. If so, it hangs the JS engine and lets the render engine work, rendering the page, and the whole process is complete.

Vue’s nextTick is a macro task or a micro task

It can be a macro task or a microtask. But the default is to use microtasks first. It falls back to macro tasks only if the host environment does not support microtasks.

Clearly, microtasks are a better choice, with higher execution efficiency. But it also makes me wonder, this.$nextTick callback can get the updated DOM. Updated DOM? Is it a rendered DOM? Wouldn’t you have to wait until an event loop is over and the browser has rendered the page to get the latest DOM? The execution of the microtask does not complete an event loop, and the new DOM element is not rendered.

To update the DOM is to update the DOM in memory, not to render it to the display. So, the callback that we register with this.$nextTick will be executed in the next microtask in order with the method that updates the DOM. You can get the updated DOM.

conclusion

Overall, event loops are an important mechanism by which JS can accomplish tasks in the host environment. Related to JS, but not within the JS language.

The above understanding is to read a number of articles, together with their own understanding of a little summary, the feeling is logical, if there are questions, welcome to point out.