头图

Guide: learned JavaScript (hereinafter referred to as JS) knows that it is a single-threaded, non-blocking scripting language. Single thread means that at any time JS code is executed, there is only one main thread to handle all tasks. This also means that JS cannot be multi-threaded programming, but JS has the ubiquitous concept of asynchronous, how do we Understand? The understanding of asynchronous and non-blocking depends on the Event Loop (Event Loop). This article will explain the Event Loop (Event Loop) around JS threads, synchronous and asynchronous, task queues, etc.

JS thread

In order to make it easier for us to understand the event loop, let's briefly understand what is called a JS thread before that. For example, the rendering process of the browser is multi-threaded, mainly including the following threads:

JS engine thread (main thread): is responsible for parsing JS scripts and running codes.

GUI rendering thread: is responsible for rendering the browser interface, parsing HTML, CSS, DOM tree and RenderObject tree, layout and drawing, etc., when the interface needs to be repainted or reflowed due to some operation, this The thread will execute.

timer trigger thread (setTimeout): The browser timer counter is not counted by the JS engine, because the JS engine is single-threaded. If it is in a blocked thread state, it will affect the accuracy of the timing. Therefore, it is timed and counted by a separate thread. Trigger timing, after the timing is completed, add it to the event queue, and wait for the JS engine to be idle before execution.

http request thread (ajax): After XMLHttpRequest is connected, a new thread request is opened through the browser. When a state change is detected, if a callback function is set at the same time, the asynchronous thread will generate a state change event, and put this callback again In the event queue, it is executed by the JS engine.

browser event trigger thread (onclick): belongs to the browser instead of the JS engine and is used to control the event loop. It can be understood as follows: The JS engine itself is too busy, and the browser needs to open another thread to assist.

main thread and rendering thread are mutually exclusive: JS engine thread and GUI rendering thread are mutually exclusive. When the JS engine is executed, the GUI thread will be suspended (equivalent to being frozen), and GUI updates will be saved in a queue It will be executed immediately when the JS engine is idle.
Browser kernel

EventLoop polling processing thread: we can understand it as an intermediary to communicate and communicate between the main thread, asynchronous thread and message queue. As shown in the figure below: from the main thread clockwise, the whole process is cyclical. Only when the synchronization code of the main thread has been executed, will it go to the queue to see what remains to be executed.

The main thread assigns setTimeout, ajax, and dom.onclick to three threads respectively, and there are some differences between them.

1. For the setTimeout code, the timer trigger thread starts timing when it receives the code, and throws the callback function into the message queue when the time is up.

2. For the ajax code, the http asynchronous thread immediately initiates the http request, and after the request is successful, the callback function is thrown into the message queue.

3. For dom.onclick, the browser event thread will listen to the dom first, and will not throw the callback function into the message queue until the dom is clicked.

synchronous and asynchronous

JS is divided into synchronous tasks and asynchronous tasks:

Synchronous task: a task queue that is executed immediately, such as a simple function;

Asynchronous tasks: request the interface to send ajax, send promise, or time timer, etc.;

Task Queue (Event Queue)

What is a task queue? It can be understood as a static queue storage structure, following the first-in-first-out principle: synchronous tasks will be executed immediately and enter the main thread; asynchronous tasks will be placed in the event queue.

Macro task queue and micro task queue

MacroTask: Overall code Script, UI rendering, setTimeout, setInterval, setImmediate (Node.js environment).

MicroTask: Promise.then(), catch, finally.

Difference: There may be multiple MacroTask queues in the event loop, and only one MicroTask queue.

MicroTask is executed before MacroTask, so if there is logic that needs to be executed first, it will be executed earlier than MacroTask in the MicroTask queue.

The following code examples can give us a full understanding of the execution order of each task:


execution stack

Both MacroTask and MicroTask are pushed into the stack for execution. JS is single-threaded, which means that there is only one main thread, and the main thread has a stack. When each function is executed, a new execution context will be generated. The execution context will contain some information such as current function parameters and local variables. It will be pushed onto the stack, and the executing context is always at the top of the stack. When the function is executed, its execution context will be popped from the stack.

summary

Synchronous and asynchronous tasks enter different execution environments respectively. The synchronous tasks are executed first, and the asynchronous tasks are placed in a circular queue. After the synchronous tasks are executed, the asynchronous tasks in the queue are executed. Asynchronous tasks perform micro tasks first, and then macro tasks. It keeps looping like this and executing it repeatedly, which is what we call Event Loop (Event Loop).

The event loop is a very important and basic concept in the JS language. Let us clearly understand the execution order of the event loop and the characteristics of each stage, so that we can have a clear understanding of the execution order of a piece of asynchronous code, thereby reducing the uncertainty of code operation. Reasonable use of various methods of delaying events helps the code to better execute according to its priority.

If you find some problems in the article during reading, you are welcome to raise them in the message, thank you for reading this article.
about the author
Ni Meng, NetEase Yunxin web front-end development engineer, is currently engaged in the development of Yunxin financial line business.


网易数智
619 声望140 粉丝

欢迎关注网易云信 GitHub: