In depth understanding of event cycle mechanism


Wechat official account: [one pot at the front end]
A little technology, a little thinking.
For questions or suggestions, please leave a message on official account.

Questions ahead:

JS is single threaded. How to be asynchronous?

What is the process of event cycle?

What are macrotask and microtask and what are their differences?

node. What is the event loop of JS and how is it different from the event loop of browser?

Processes and threads

The browser is multi process, including:

  • Browser process: there is only one main process of the browser (responsible for coordination and control);
  • Third party plug-in process: each type of plug-in corresponds to a process, which is created only when the plug-in is used;
  • GPU process: at most one, used for 3D rendering;
  • Browser rendering process (kernel): by default, there is one process for each tab page, which does not affect each other. It controls page rendering, script execution, event processing, etc. (sometimes it will be optimized, for example, multiple blank tabs will be merged into one process).

The browser rendering process is the process mainly used by the front-end page, including the following threads:

  • GUI rendering thread (responsible for rendering pages, parsing HTML, forming DOM tree with CSS, and mutually exclusive with JS engine)
  • JS engine thread
  • Event triggered thread
  • Timer trigger thread
  • HTTP request thread and other main threads

About threads in execution:

Main thread: that is, the thread executed by JS engine. There is only one thread. Page rendering and function processing are executed on this main thread.

Worker thread: also known as the behind the scenes thread. This thread may exist in the browser or JS engine and is separate from the main thread to handle asynchronous events such as file reading and network requests.

event loop

All tasks can be divided into synchronous tasks and asynchronous tasks. Synchronous tasks, as the name suggests, are tasks to be executed immediately. Synchronous tasks generally enter the main thread directly for execution. Asynchronous tasks are tasks executed asynchronously, such as Ajax network requests and setTimeout timing functions. Asynchronous tasks are coordinated through the mechanism of task queue (first in first out mechanism).

Synchronous and asynchronous tasks enter different execution environments respectively. They enter the main thread synchronously, that is, the main execution stack, and enter the task queue asynchronously. If the task in the main thread is empty after execution, it will go to the task queue to read the corresponding task and push it into the main thread for execution. The continuous repetition of the above process is what we call event loop.

In the event cycle, each cycle operation is called tick, and its key steps can be summarized as follows:

  1. At first, the whole script is executed as a macro task
  2. During execution, the synchronization code is directly executed, the macro task enters the macro task queue, and the micro task enters the micro task queue
  3. After the current macro task is executed, get out of the queue, read the micro task list, and execute it in turn until all the macro tasks are executed
  4. Read the macro task list, if any, execute it successively until all are executed
  5. Perform rendering of the browser UI thread
  6. Check whether there are web worker tasks, and execute if there are
  7. After executing this round of macro tasks, return to step 2 and continue the cycle until the macro task and micro task queues are empty

Macro task and micro task

JS engine divides all tasks into two categories, one is called macro task and the other is called micro task.

Macro tasks mainly include:

  • JS (overall code)
  • I / O, UI rendering
  • MessageChannel、postMessage
  • Setimmediate (node. JS environment)
  • setTimeout、setInterval
  • Requestanimationframe belongs to the GUI engine, which occurs in the redrawing and rearrangement part of the rendering process and is executed before UI rendering

Micro tasks mainly include:

  • process. Nexttick (node. JS environment)
  • Mutaionobserver (browser environment)
  • Promise

Execute the micro task before executing the macro task.

Node. JS event loop

The event loop is node JS mechanism for handling non blocking I / O operations. At present, most kernels are multithreaded, which can handle a variety of operations in the background. When one of the operations is completed, the kernel notifies the node JS adds the appropriate callback function to the polling queue and waits for the opportunity to execute.

When node After JS is started, it will initialize the event loop and process the provided input script. It may call some asynchronous APIs, schedule timers, or call process Nexttick(), and then start processing the event loop.

The following is node JS event cycle sequence:

  1. Timers: execute the expired setTimeout and setinterval callbacks.
  2. Pending callbacks: a pending callback function that executes I / O callbacks that are delayed to the next iteration of the loop. Performs a callback on certain system operations, such as TCP error types.
  3. Idle, prepare: idle preparation, which is used inside the node system.
  4. Poll: retrieve new I / O events. Callback for I / O (such as file and network), except for close, timer and setimmediate. In other cases, the node will be blocked here at an appropriate time.
  5. Check: execute setimmediate callback.
  6. Close callbacks: execute close event callback, such as socket on(‘close’, …)、 HTTP close, etc.

The above is the execution order of macro tasks, node JS also executes micro tasks before macro tasks. Micro tasks mainly include process Nexttick and promise, where process Nexttick executes first.

Finally, JavaScript is a single threaded language. Asynchronous operations are put in the event loop queue and wait for the main execution stack to execute. There is no special asynchronous execution thread.