In addition to Weibo, there is also WeChat
Please pay attention
WeChat public account
Shulou
2025-02-27 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Development >
Share
Shulou(Shulou.com)06/02 Report--
This article introduces the knowledge of "what is the concurrency model and event loop mechanism of JavaScript". In the operation of actual cases, many people will encounter such a dilemma, so let the editor lead you to learn how to deal with these situations. I hope you can read it carefully and be able to achieve something!
Single-threaded language
In the browser implementation, each single page is an independent process, including JS engine, GUI interface rendering, event triggers, timing triggers, asynchronous HTTP requests and other threads.
The Process is the smallest unit of resource allocation such as the operating system CPU. It is the execution entity of the program and the container of the thread. Thread is the smallest unit that the operating system can schedule operations. A thread refers to a single order of control flow in a process.
So we can say that JS is a "single-threaded" language, where the code can only be executed serially in a single order and block other code until the execution is complete.
JS data structure
Several important data structures of JS:
● stack (Stack): function nested calls for JS, last-in, first-out, until the stack is cleared.
● heap (Heap): the area of memory used to store large chunks of data, such as objects.
● queue (Queue): for the event loop mechanism, first-in, first-out, until the queue is empty.
Event cycle
Our experience tells us that JS can be executed concurrently, such as scheduled tasks and concurrent AJAX requests, so how is this done? In fact, all these are done by JS simulating multithreading with a single thread.
As shown in the figure above, JS serially executes the main thread task, and when it encounters an asynchronous task such as a timer, it puts it into the event queue. After the main thread task is finished, it traverses the event queue to retrieve the queue leader task for execution until the queue is empty.
After all execution is completed, there will be a master monitoring process that continuously checks whether the queue is empty, and if not, continues the event loop.
SetTimeout scheduled task
The scheduled task setTimeout (fn, timeout) will be handed over to the browser's timer module first, and then put the event into the event queue when the delay time is up. After the execution of the main thread, if there are no other tasks in the queue, it will be processed immediately. If there are any tasks that have not been completed, they will not be executed until all the previous tasks have been executed. So the second parameter of setTimeout is the minimum delay time, not the wait time.
When we expect an operation to be onerous and time-consuming and do not want to block the execution of the main thread, we use the immediate execution task:
SetTimeout (fn, 0)
Special scenario 1: the minimum delay is 1ms
However, consider how such a piece of code will be executed:
SetTimeout (() = > {console.log (5)}, 5) setTimeout (() = > {console.log (4)}, 4) setTimeout (() = > {console.log (3)}, 3) setTimeout (() = > {console.log (2)}, 2) setTimeout (() = > {console.log (1)}, 1) setTimeout (() = > {console.log (0)}, 0)
After understanding the event queuing mechanism, your answer should be 0Magol 1je 2je 3je 4je 5, but the answer is 1je 0je 2je 3pm 4je 5, this is because the browser's implementation mechanism is the minimum interval of 1ms.
/ / https://github.com/nodejs/node/blob/v8.9.4/lib/timers.js#L456if (! (after > = 1 & & after {setTimeout (resolve, ms);})} / / use async function test () {await sleep (3000);}
Async await mechanism
The async function is the syntactic sugar of the Generator function, providing more convenient calls and semantics. The above use can be replaced by:
Function* test () {yield sleep (3000);} / / use var g = test (); test.next ()
But the use of the call is more complex, so generally we can use the async function. But how to implement the sleep function in JS is to provide an intermediate state pause during execution, then hand over control, and continue execution from the last breakpoint when the control is handed back. So it creates the illusion that the JS main thread can perform other tasks as well.
When the Generator function is called, it returns an internal pointer to the pause point of multiple asynchronous tasks. When the next function is called, execution starts from the last pause point.
Cooperative process
Coroutine is a solution of multi-task asynchronous execution in which multiple threads cooperate with each other to complete asynchronous tasks. The process of his operation:
● co-program A starts execution
● protocol An is halfway through execution, the execution is suspended, and the execution power is transferred to program B.
After the ● protocol B has been executed for a period of time, it will exchange the execution power to A
● protocol A resumes execution
You can see that this is the implementation of the Generator function.
Macro task and micro task
The task of an JS can be defined as: in the standard execution mechanism, all blocks of code that will be scheduled for execution.
We described how JS uses a single thread to complete asynchronous multitasking calls, but we know that there are many kinds of asynchronous tasks in JS, such as setTimeout timers, Promise asynchronous callback tasks, etc., do they have the same execution priority?
The answer is no. JS has a more detailed division of asynchronous tasks, which is divided into two categories:
The Macro Task (macrotask) consists of:
A block of JS code executed by ●, such as the console, the content contained in the script element.
A callback function bound to the ● event, such as a click event.
Callbacks created by ● timers, such as setTimeout and setInterval.
Micro tasks (microtask) include:
The thenable function of the ● Promise object.
The process.nextTick function in ● Nodejs.
The queueMicrotask () function specific to ● JS.
Both macro and micro tasks have their own event loop mechanism and independent event queues (Event Queue), which are executed in the order of the queues. But there are two main differences between macro tasks and micro tasks:
1. The execution of the macro task is completed, and all tasks in the micro task queue are completed before the control is returned to the main thread to execute other macro tasks.
2. New micro-tasks created by micro-tasks will be traversed until the next macro task is executed until the micro-task queue is empty.
Browser processes and threads
The browser is multi-process, and each page and plug-in is a separate process, which ensures that a single page crash or plug-in crash will not affect the stable operation of other pages and browsers as a whole.
It mainly includes:
1, the main process: responsible for browser interface display and management, such as forward, backward, add, close, download and manage network resources.
2. Third-party plug-in process: when the plug-in is enabled, each plug-in has an independent process.
3. GPU process: globally unique, used for 3D graphics drawing.
4, Renderer rendering process: each page a process, do not affect each other, the execution of event handling, script execution, page rendering.
Single page thread
A single page in a browser is a process, which refers to a Renderer process, and the process contains multiple threads for handling different tasks, including:
1. GUI rendering thread: responsible for building HTML and CSS into DOM trees, rendering pages, such as redrawing.
2. JS engine threads: the JS kernel, such as Chrome's V8 engine, is responsible for parsing and executing JS code.
3. Event trigger thread: when there is a binding callback for events such as clicks, it will be put into the macro task event queue after it is triggered.
4. Timing trigger thread: the timing counter of setTimeout and setInterval is put into the macro task event queue when the time arrives.
5. Asynchronous HTTP request thread: a new thread is opened after the XMLHTTPRequest request, and after waiting for the state to change, if there is a callback function, it will be placed in the macro task queue.
It is important to note that the GUI rendering process and the JS engine process are mutually exclusive, and only one will be executed at the same time. The main reason is to save money, because the execution of JS may change the page many times, and page changes will call JS many times, such as resize. Therefore, the strategy adopted by the browser is to execute alternately. After each macro task is completed, GUI rendering is performed, and then the next macro task is executed.
Webworker thread
Because JS has only one engine thread and is mutually exclusive with the GUI rendering thread, it can cause the page to get stuck when heavy tasks are executed, so Webworker is supported in HTML5, which is used to request a new child thread from the browser to execute the task and communicate with the worker thread through postMessage API. So when we execute heavy tasks, we can choose to open a new worker thread to execute, and communicate to the main thread after execution, which will not affect the normal rendering and use of the page.
Summary
1. JS is a single-threaded, blocking execution language.
2. JS completes the concurrent execution of asynchronous tasks through the event loop mechanism.
3. JS subdivides tasks into macro tasks and micro tasks to provide execution priority.
4. The single page of the browser is a process, which contains JS engine threads and GUI rendering threads that are mutually exclusive. You can complete heavy computing tasks by opening new Web Worker threads.
Finally, give you an examination question, you can guess the output of the implementation to verify the learning results:
Function sleep (ms) {console.log ('before first microtask init'); new Promise (resolve = > {console.log (' first microtask'); resolve ()}). Then () = > {console.log ('finish first microtask')}); console.log (' after first microtask init'); return new Promise (resolve = > {console.log ('second microtask'); setTimeout (resolve, ms);}) } setTimeout (async () = > {console.log ('start task'); await sleep (3000); console.log (' end task');}, 0); setTimeout () = > console.log ('add event'), 0); console.log (' main thread')
The output is:
This is the end of main threadstart taskbefore first microtask initfirst microtaskafter first microtask initsecond microtaskfinish first microtaskadd eventend task's "what is the concurrency model and event loop mechanism of JavaScript". Thank you for reading. If you want to know more about the industry, you can follow the website, the editor will output more high-quality practical articles for you!
Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.
Views: 0
*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.
Continue with the installation of the previous hadoop.First, install zookooper1. Decompress zookoope
"Every 5-10 years, there's a rare product, a really special, very unusual product that's the most un
© 2024 shulou.com SLNews company. All rights reserved.