Home Web Front-end JS Tutorial Can JavaScript implement multi-threading? In-depth understanding of JavaScript timing mechanism_javascript skills

Can JavaScript implement multi-threading? In-depth understanding of JavaScript timing mechanism_javascript skills

May 16, 2016 pm 06:38 PM
javascript Multithreading

JavaScript timers that are easy to deceive other people’s feelings

JavaScript’s setTimeout and setInterval are two methods that are easy to deceive other people’s feelings, because we often start to think that when called, it will be executed in the established way. , I think many people feel the same way. For example,
Copy code The code is as follows:

setTimeout( function(){ alert('Hello!'); } , 0);
setInterval( callbackFunction , 100);

Think that the greeting method in setTimeout will be executed immediately, Because this is not said out of thin air, but the JavaScript API document clearly defines the meaning of the second parameter as the number of milliseconds after which the callback method will be executed. If it is set to 0 milliseconds, of course it will be executed immediately.
Same as You have no doubt that the callbackFunction method of setInterval will be executed immediately every 100 milliseconds!

But as your JavaScript application development experience continues to increase and enrich, one day you find a weird piece of code and you are puzzled. The solution:
Copy the code The code is as follows:

div.onclick = function(){
setTimeout( function(){document.getElementById('inputField').focus();}, 0);
};

Since it is executed after 0 milliseconds, then use What is setTimeout doing? At this moment, your firm belief has begun to waver.

Until the last day, you accidentally wrote a piece of bad code:
Copy code The code is as follows:

setTimeout( function(){ while(true){} } , 100);
setTimeout( function(){ alert(' Hello!'); } , 200);
setInterval( callbackFunction , 200);

The first line of code enters an infinite loop, but soon you will find that the second and third lines are not what you expected, the alert greeting does not appear, and there is no news from the callbacKFunction!

At this time, you are completely confused. This situation is difficult to accept, because the process of changing the long-established cognition to accept new ideas is painful, but the facts are before you, and the search for the truth of JavaScript will not be because of pain. And stop, let us start the journey of exploring JavaScript threads and timers!

Open the clouds and see the moonlight

The main reason for all the above misunderstandings is: subconsciously believing that, The JavaScript engine has multiple threads executing, and the timer callback function of JavaScript is executed asynchronously.

In fact, JavaScript uses a blinding method to deceive our eyes most of the time. The backlight needs to be clarified here. A fact:

The JavaScript engine runs in a single thread. The browser has only one thread running the JavaScript program at any time.
It also makes sense for the JavaScript engine to run in a single thread. Single thread Don't worry about the complex issues of thread synchronization, the problem is simplified.

So how does the single-threaded JavaScript engine cooperate with the browser kernel to process these timers and respond to browser events?
The following is combined with the browser A brief explanation of the kernel processing method.

The browser kernel implementation allows multiple threads to execute asynchronously. These threads cooperate with each other under kernel control to maintain synchronization. If a browser kernel implementation has at least three resident threads :javascript engine thread, interface rendering thread, browser event triggering thread. In addition to these, there are also some threads that terminate after execution, such as HTTP request thread. These asynchronous threads will generate different asynchronous events. The following is a diagram to illustrate the single How the thread's JavaScript engine interacts and communicates with other threads. Although the implementation details of each browser kernel are different, the calling principles are similar.

As can be seen from the picture, browse The JavaScript engine in the browser is event-driven. The events here can be regarded as various tasks assigned to it by the browser. These tasks can originate from the code block currently executed by the JavaScript engine, such as calling setTimeout to add a task, or you can Other threads from the browser kernel, such as interface element mouse click events, scheduled trigger time arrival notifications, asynchronous request status change notifications, etc. From a code perspective, the task entities are various callback functions, and the JavaScript engine has been waiting for the task queue Arrival of tasks. Due to the single-thread relationship, these tasks have to be queued and processed by the engine one after another.

T1-t2..tn in the above figure represents different time points, and the corresponding small squares below tn represent the For tasks at a time point, assuming that it is time t1, the engine is running in the task block code corresponding to t1. At this point in time, let us describe the status of other threads in the browser kernel.

T1 time:

GUI rendering thread:

This thread is responsible for rendering the HTML elements of the browser interface. When the interface needs to be repainted (Repaint) or a reflow is caused by some operation , the thread will be executed. Although this article focuses on explaining the JavaScript timing mechanism, it is necessary to talk about the rendering thread at this time, because this thread and the JavaScript engine thread are mutually exclusive, which is easy to understand, because JavaScript scripts can manipulate DOM elements. When modifying the attributes of these elements and rendering the interface at the same time, the element data obtained before and after the rendering thread may be inconsistent.

While the JavaScript engine is running the script, the browser rendering thread is in a suspended state, that is to say is "frozen".
Therefore, updates to the interface performed in the script, such as adding nodes, deleting nodes, or changing the appearance of nodes, will not be reflected immediately. These operations will be saved in a In the queue, the JavaScript engine will have a chance to render when it is idle. Maybe you have a question here, why is the interface updated when the alert of the JS code block occurs, isn't JS running? In fact, when the alert occurs, the browser kernel The JavaScript engine thread will be suspended and the interface will be updated.

GUI event triggering thread:

The execution of the JavaScript script does not affect the triggering of the html element event. During the t1 time period, the user first clicks a mouse button. The click is captured by the browser event trigger thread and forms a mouse click event. As can be seen from the figure, for the JavaScript engine thread, this event is asynchronously transmitted to the task from other threads. At the end of the queue, because the engine is processing the task at t1, this mouse click event is waiting to be processed.

Timing trigger thread:

Note that the browser model timing counter here is not counted by the JavaScript engine, because the JavaScript engine is single-threaded. If it is in a blocked thread state, it cannot count the time. It must rely on the outside to time and trigger the timing. Therefore, the scheduled events in the queue are also asynchronous events.

As can be seen from the figure, during this t1 time period, after the mouse click event is triggered, the previously set setTimeout timing has also arrived. At this time, it is very important for the JavaScript engine Say, the scheduled trigger thread generates an asynchronous scheduled event and puts it in the task queue. The event is queued after the click event callback and waits for processing.
Similarly, still within the t1 time period, a certain setInterval is scheduled next The trigger has also been added. Due to interval timing, it was triggered twice in succession within the t1 period. These two events were queued to the end of the queue to be processed.

It can be seen that if the time period t1 is very long, Yuanda is based on the setInterval timing interval, then the timing trigger thread will continuously generate asynchronous timing events and put them at the end of the task queue regardless of whether they have been processed. However, once t1 and the tasks in front of the first timing event have been processed, these The scheduled events in the queue are executed in sequence without interruption. This is because, for the JavaScript engine, each task in the processing queue is processed in the same way, but the order of processing is different.

After t1, that is to say, the currently processed task has been returned. The JavaScript engine will check the task queue and find that the current queue is not empty, and then take out the corresponding task under t2 for execution, and so on at other times. From this point of view:

If the queue is not empty, the engine will take out a task from the head of the queue until the task is processed, that is, after returning, the engine will run the next task. Other tasks in the queue cannot be executed before the task returns.
You can try running the following example for testing. The first timer is an infinite loop, and the second timer outputs a string of characters to the interface. The first timer comes earlier than the second timer.
Copy code The code is as follows:

setTimeout(function(){
for(; ;);
}, 50);
setTimeout(function(){alert('Hello');}, 51);

After running, it can be seen that when there is no browsing The second timer alert will not pop up before the server prompts that the script is busy. Because of the single-thread relationship, the second script has no chance to run until the first timer callback script returns.

I believe you Now it is clear whether JavaScript can be multi-threaded, and we also understand the running mechanism of JavaScript timer. Let’s analyze some cases:

Case 1: setTimeout and setInterval
Copy code The code is as follows:

setTimeout(function(){
/* Code block... */
setTimeout(arguments.callee, 10);
}, 10);

setInterval(function(){
/*code block... */
}, 10);

The two pieces of code look the same together, but in fact they are not. The setTimeout in the callback function in the first paragraph sets a new setTimeout timing after the JavaScript engine is executed. It is assumed that the previous callback is processed until the next one. A callback starts to be processed as a time interval. Theoretically, the execution time interval of two setTimeout callbacks is >= 10ms. In the second section, after the setInterval is set, the timing trigger thread will continuously generate asynchronous timing events every ten seconds and put them in At the end of the task queue, theoretically the execution time interval between two setInterval callbacks is
Case 2: Is the asynchronous ajax request really asynchronous?

Many classmates and friends I'm not sure, since JavaScript is said to run in a single thread, is XMLHttpRequest really asynchronous after connecting?
In fact, the request is indeed asynchronous, but this request is made by the browser to open a new thread request (see the picture above) , when the requested status changes, if a callback has been set previously, the asynchronous thread will generate a status change event and put it in the JavaScript engine's processing queue to wait for processing. When the task is processed, the JavaScript engine always runs the callback function in a single thread. Specifically, Click to still run the function set by onreadystatechange in a single thread.
Statement of this Website
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn

Hot AI Tools

Undresser.AI Undress

Undresser.AI Undress

AI-powered app for creating realistic nude photos

AI Clothes Remover

AI Clothes Remover

Online AI tool for removing clothes from photos.

Undress AI Tool

Undress AI Tool

Undress images for free

Clothoff.io

Clothoff.io

AI clothes remover

Video Face Swap

Video Face Swap

Swap faces in any video effortlessly with our completely free AI face swap tool!

Hot Article

Roblox: Bubble Gum Simulator Infinity - How To Get And Use Royal Keys
3 weeks ago By 尊渡假赌尊渡假赌尊渡假赌
Nordhold: Fusion System, Explained
3 weeks ago By 尊渡假赌尊渡假赌尊渡假赌
Mandragora: Whispers Of The Witch Tree - How To Unlock The Grappling Hook
3 weeks ago By 尊渡假赌尊渡假赌尊渡假赌

Hot Tools

Notepad++7.3.1

Notepad++7.3.1

Easy-to-use and free code editor

SublimeText3 Chinese version

SublimeText3 Chinese version

Chinese version, very easy to use

Zend Studio 13.0.1

Zend Studio 13.0.1

Powerful PHP integrated development environment

Dreamweaver CS6

Dreamweaver CS6

Visual web development tools

SublimeText3 Mac version

SublimeText3 Mac version

God-level code editing software (SublimeText3)

Hot Topics

Java Tutorial
1664
14
PHP Tutorial
1269
29
C# Tutorial
1249
24
C++ function exceptions and multithreading: error handling in concurrent environments C++ function exceptions and multithreading: error handling in concurrent environments May 04, 2024 pm 04:42 PM

Function exception handling in C++ is particularly important for multi-threaded environments to ensure thread safety and data integrity. The try-catch statement allows you to catch and handle specific types of exceptions when they occur to prevent program crashes or data corruption.

How to implement multi-threading in PHP? How to implement multi-threading in PHP? May 06, 2024 pm 09:54 PM

PHP multithreading refers to running multiple tasks simultaneously in one process, which is achieved by creating independently running threads. You can use the Pthreads extension in PHP to simulate multi-threading behavior. After installation, you can use the Thread class to create and start threads. For example, when processing a large amount of data, the data can be divided into multiple blocks and a corresponding number of threads can be created for simultaneous processing to improve efficiency.

How can concurrency and multithreading of Java functions improve performance? How can concurrency and multithreading of Java functions improve performance? Apr 26, 2024 pm 04:15 PM

Concurrency and multithreading techniques using Java functions can improve application performance, including the following steps: Understand concurrency and multithreading concepts. Leverage Java's concurrency and multi-threading libraries such as ExecutorService and Callable. Practice cases such as multi-threaded matrix multiplication to greatly shorten execution time. Enjoy the advantages of increased application response speed and optimized processing efficiency brought by concurrency and multi-threading.

How do PHP functions behave in a multi-threaded environment? How do PHP functions behave in a multi-threaded environment? Apr 16, 2024 am 10:48 AM

In a multi-threaded environment, the behavior of PHP functions depends on their type: Normal functions: thread-safe, can be executed concurrently. Functions that modify global variables: unsafe, need to use synchronization mechanism. File operation function: unsafe, need to use synchronization mechanism to coordinate access. Database operation function: Unsafe, database system mechanism needs to be used to prevent conflicts.

How to deal with shared resources in multi-threading in C++? How to deal with shared resources in multi-threading in C++? Jun 03, 2024 am 10:28 AM

Mutexes are used in C++ to handle multi-threaded shared resources: create mutexes through std::mutex. Use mtx.lock() to obtain a mutex and provide exclusive access to shared resources. Use mtx.unlock() to release the mutex.

Usage of JUnit unit testing framework in multi-threaded environment Usage of JUnit unit testing framework in multi-threaded environment Apr 18, 2024 pm 03:12 PM

There are two common approaches when using JUnit in a multi-threaded environment: single-threaded testing and multi-threaded testing. Single-threaded tests run on the main thread to avoid concurrency issues, while multi-threaded tests run on worker threads and require a synchronized testing approach to ensure shared resources are not disturbed. Common use cases include testing multi-thread-safe methods, such as using ConcurrentHashMap to store key-value pairs, and concurrent threads to operate on the key-value pairs and verify their correctness, reflecting the application of JUnit in a multi-threaded environment.

Challenges and countermeasures of C++ memory management in multi-threaded environment? Challenges and countermeasures of C++ memory management in multi-threaded environment? Jun 05, 2024 pm 01:08 PM

In a multi-threaded environment, C++ memory management faces the following challenges: data races, deadlocks, and memory leaks. Countermeasures include: 1. Use synchronization mechanisms, such as mutexes and atomic variables; 2. Use lock-free data structures; 3. Use smart pointers; 4. (Optional) implement garbage collection.

Challenges and strategies for testing multi-threaded programs in C++ Challenges and strategies for testing multi-threaded programs in C++ May 31, 2024 pm 06:34 PM

Multi-threaded program testing faces challenges such as non-repeatability, concurrency errors, deadlocks, and lack of visibility. Strategies include: Unit testing: Write unit tests for each thread to verify thread behavior. Multi-threaded simulation: Use a simulation framework to test your program with control over thread scheduling. Data race detection: Use tools to find potential data races, such as valgrind. Debugging: Use a debugger (such as gdb) to examine the runtime program status and find the source of the data race.

See all articles