“JavaScript is single-threaded”, Js developers have always thought so. But today we are going to introduce multi-threaded programming in JavaScript, you heard me right, I am talking about Multi-Threaded Programming - Web Workers .
I. Preface
Web Workers is a feature of the browser (the host environment), not a standard feature of JavaScript, so what does it do?
Suppose you click a button on a page and it triggers the execution of a series of intensive tasks that take tens of seconds or even minutes to complete, then the UI will be stuck, resulting in a Page Unresponsive error. You definitely don’t want this to happen, and it can lead to a very bad user experience.
You want a way to let the main thread continue to render the UI, while the processing of intensive tasks to another child thread to take charge, and when the child thread is finished, the main thread can get the results of the child thread and react. This is where Web Workers comes in.
You can create a Web worker in the main thread, give some time-consuming tasks to the Web worker, and when the Web worker finishes processing the tasks, it will return the results to the main thread. This will not lead to Page Unresponsive situation.
The Web Workers mechanism differs from the multithreading in C++ and C# in that the child threads (Web workers) cannot share memory with other threads (main threads). This is an advantage, shared memory means shared scope and resources. If memory is shared, then you will encounter all the problems that other multi-threaded languages (C++, C#, etc.) have to face, such as cooperative or preemptive locking mechanisms (mutex, etc.), and that would be too much of a problem.
Once a Worker thread is created successfully, it will always run, so it should be closed after it is used, otherwise it will take up too many resources.
Web Worker has the following points to note when using it.
(1) Homologation restriction
The script file assigned to the worker thread must be the same source as the script file of the main thread.
(2) DOM restriction
The global object where the worker thread is located is not the same as the main thread, so it cannot read the DOM
object of the web page where the main thread is located, and it cannot use the document
, window
, parent
objects. However, the Worker
thread can read the navigator
object and the location
object.
(3) Communication links
The worker thread and the main thread are not in the same context, and they cannot communicate directly, but must do so via messages.
(4) Scripting restrictions
The worker thread cannot execute the alert()
method and the confirm()
method, but can use the XMLHttpRequest
object to make AJAX
requests.
(5) File restrictions
The Worker
thread cannot read local files, i.e. it cannot open the local file system (file://), and the scripts it loads must come from the network.
II. Usage
1. Main thread
Create a new Worker thread inside the main thread.
|
|
The argument to the Worker()
constructor is a script file, which is the execution code of the Worker thread.
The main thread communicates with the Worker via message, calling the worker.postMessage()
method to send a message to the Worker. The Worker, upon receiving the message from the main thread, can process the task according to the message content (how to process the task according to the message will be explained later).
|
|
The argument to postMessage()
can be any type of data, including binary.
The main thread can receive messages from child threads by listening to the message
event through the worker and getting the data through event.data
, similar to how other events are handled.
There are two ways to do this, onmessage()
or addEventListener()
.
(1) onmessage()
(2)addEventListener()
After the worker finishes its task, the main thread closes the worker with worker.terminate()
.
2. Worker sub-threads
The main thread sends a message to the worker thread by triggering the message
event via worker.postMessage
, and the worker can receive messages from the main thread by listening to the message
event.
The global object in the child thread is the self
keyword, not window
. worker’s message
event is the same as other dom events, so there are several ways to listen for events.
(1) Use self.addEventListener()
.
(2) Use self.onmessage()
.
3. Worker can load scripts
Worker can load scripts via importScripts()
.
4. Listening for errors
The main thread can listen for errors. If an error occurs, Worker will trigger the error
event.
(1) worker.onerror()
.
(2) worker.addEventListener
。
5. worker is done, remember to close
III. A Case
The following is a demo to find all the prime numbers in a specified range of numbers. It is rather time consuming, so the process of finding and calculating is put into the Worker to handle. You can click the following link to see the running effect.