Comments: Web Worker in HTML5 can be divided into two different thread types: one is the Dedicated thread Dedicated Worker and the other is the Shared thread Shared Worker. The two types of threads have different purposes. If you are interested, you may find them helpful.Javascript execution mechanism
Before HTML5, JavaScript in the browser runs in the form of a single thread. Although multiple methods have been used to simulate multithreading (for example, the setinterval method in Javascript, setTimeout method), but in essence, the program is still run by the JavaScript engine in a single thread scheduling mode. The working threads introduced in HTML5 allow the browser-side Javascript Engine to execute Javascript code concurrently, thus achieving good support for browser-side multi-thread programming.
Multithreading in Javascript-WebWorker
Web Worker in HTML5 can be divided into two different thread types: one is the Dedicated thread Dedicated Worker and the other is the Shared thread Shared Worker. The two types of threads have different purposes.
Dedicated web worker
A dedicated worker is connected with the script used to create it. It can communicate with other worker or browser components, but cannot communicate with DOM. Specifically, I think this thread only processes one requirement at a time. Dedicated threads are implemented in all mainstream browsers except IE, so you can use them with confidence.
Create thread
Creating a worker is simple. You only need to pass the file name of the JavaScript file that needs to be executed in the thread to the constructor.
Thread Communication
Communication between the main thread and the sub-thread uses the postMessage and onmessage methods of the thread object. No matter who sends the data, the postMessage method is used to send the data, and the receiver uses the onmessage method to receive the data. PostMessage only has one parameter, that is, the transmitted data, and onmessage only has one parameter. If it is an event, the received data is obtained through event. data.
Send JSON data
JSON is supported by JS native. You don't need to use it for white. You can use JSON to transmit complicated data. For example:
The Code is as follows:
PostMessage ({'cmd': 'init', 'timestamp': Date. now ()});
Handling error
When a thread encounters an error, its onerror Event Callback will be called. Therefore, the error handling method is simple, that is, the onerror event of the thread instance. This callback function has an error parameter, which has three fields: message-error message, filename-script file with an error, and lineno-row with an error.
Destroy thread
Inside the thread, use the close method to destroy itself. In the main thread outside the thread, use the terminate method of the thread instance to destroy the thread.
The following shows the basic operations of a thread from an example:
HTML code:
The Code is as follows:
<! Doctype html>
<Html>
<Head>
<Meta http-equiv = "Content-Type" content = "text/html; charset = UTF-8"/>
<Title> web worker fibonacci </title>
<Script type = "text/javascript">
Onload = function (){
Var worker = new Worker ('pythonacci. js ');
Worker. onmessage = function (event ){
Console. log ("Result:" + event. data );
};
Worker. onerror = function (error ){
Console. log ("Error:" + error. message );
};
Worker. postMessage (40 );
}
</Script>
</Head>
<Body>
</Body>
</Html>
Script file:
The Code is as follows:
// Maid. js
Var maid = function (n ){
Return n <2? N: arguments. callee (n-1) + arguments. callee (n-2 );
};
Onmessage = function (event ){
Var n = parseInt (event. data, 10 );
PostMessage (maid (n ));
};
Put them in the same directory, run the page file, view the console, and you can see the running results.
Here is another point. In the main thread, the onmessage event can be mounted in another way:
The Code is as follows:
Worker. addEventListener ('message', function (event ){
Console. log ("Result:" + event. data );
}, False );
I personally think it is very troublesome. It is better to use onmessage directly.
Use other script files
The worker thread can use the global method importScripts to load and use other intra-domain script files or class libraries. For example, the following are valid usage methods:
The Code is as follows:
ImportScripts ();/* imports nothing */
ImportScripts ('foo. js');/* imports just "foo. js "*/
ImportScripts ('foo. js', 'bar. js');/* imports two scripts */
After the import, you can directly use the methods in these files. Let's look at a small online example:
The Code is as follows:
/**
* Use the importScripts method to introduce external resource scripts. Here we use the math_utilities.js mathematical formula library.
* When the JavaScript engine loads the resource file, it continues to execute the following code. At the same time, the following code can be accessed and called
* Variables and methods defined in the resource file.
**/
ImportScripts ('math _ utilities. js ');
Onmessage = function (event)
{
Var first = event. data. first;
Var second = event. data. second;
Calculate (first, second );
};
Function calculate (first, second ){
// Do the calculation work
Var common_divisor = divisor (first, second );
Var common_multiple = multiple (first, second );
PostMessage ("Work done! "+
"The least common multiple is" + common_divisor +
"And the greatest common divisor is" + common_multiple );
}
Some online users think of using the importScripts method to solve the problem of resource pre-loading (the browser preloads resources without parsing and executing the resources). The principle is also very simple.
Thread nesting
You can also create sub-threads in the work thread. The operations are the same.
Synchronization problems
Worker does not have a lock mechanism. multi-thread synchronization can only be solved by Code (for example, defining signal variables ).
Shared SharedWebWorker
Shared web worker is mainly applicable to the problem of multi-connection concurrency. Because you need to process multiple connections, its API and dedicated worker are slightly different. In addition, the shared-type web worker and dedicated-type worker cannot access DOM, and the access to form attributes is also limited. Shared web worker does not support communication.
The page script can communicate with the shared web worker. However, it is slightly different from the dedicated web worker (using an implicit port communication, communication is performed explicitly by using a port object and attaching a message event handler.
After receiving the first message of the web worker script, the shared web worker attaches an event handler to the active port. Generally, the handler runs its own postMessage () method to return a message to the calling code, and then the start () method of the port generates a valid message process.
The only example that can be found on the Internet: Create a sharing thread to receive commands sent from different connections, and then implement its own command processing logic, after the instruction is processed, the result is returned to different connected users.
HTML code:
The Code is as follows:
<! DOCTYPE html>
<Html>
<Head>
<Meta charset = "UTF-8">
<Title> Shared worker example: how to use shared worker in HTML5 </title>
<Script>
Var worker = new SharedWorker ('sharedworker. js ');
Var log = document. getElementById ('response _ from_worker ');
Worker. port. addEventListener ('message', function (e ){
// Log the response data in web page
Log. textContent = e. data;
}, False );
Worker. port. start ();
Worker. port. postMessage ('Ping from user web page ..');
// Following method will send user input to sharedworker
Function postMessageToSharedWorker (input)
{
// Define a json object to construct the request
Var instructions = {instruction: input. value };
Worker. port. postMessage (instructions );
}
</Script>
</Head>
<Body onload = ''>
<Output id = 'response _ from_worker '>
Shared worker example: how to use shared worker in HTML5
</Output>
Send instructions to shared worker:
<Input type = "text" autofocus oninput = "postMessageToSharedWorker (this); return false;">
</Input>
</Body>
</Html>
Script File Code:
The Code is as follows:
// Create a sharing thread to receive commands sent from different connections. After the command is processed, the result is returned to different connection users.
Var connect_number = 0;
Onconnect = function (e ){
Connect_number = connect_number + 1;
// Get the first port here
Var port = e. ports [0];
Port. postMessage ('a new connection! The current connection number is'
+ Connect_number );
Port. onmessage = function (e ){
// Get instructions from requester
Var instruction = e. data. instruction;
Var results = execute_instruction (instruction );
Port. postMessage ('request: '+ instruction + 'response' + results
+ 'From shared worker ...');
};
};
/*
* This function will be used to execute the instructions send from requester
* @ Param instruction
* @ Return
*/
Function execute_instruction (instruction)
{
Var result_value;
// Implement your logic here
// Execute the instruction...
Return result_value;
}
In the preceding example of a shared thread, a shared thread object is constructed on the home page, that is, the connection page of each user. Then, a method postMessageToSharedWorker is defined to send USER commands to the shared thread. At the same time, connect_number is defined in the implementation code snippet of the Sharing thread to record the total number of connections to this sharing thread. Then, the onconnect event processor is used to receive connections from different users and parse the commands they pass. Finally, the execute_instruction method is defined to execute USER commands. After the command is executed, the result is returned to each user.
Here we didn't use the onmessage event processor of the working thread as in the preceding example, but used another method of addEventListener. In fact, as mentioned above, the implementation principles of these two methods are basically the same, but there are some slight differences here. If addEventListener is used to receive messages from the sharing thread, you need to use worker first. port. start () method to start this port. Then, you can receive and send messages as normally as the working thread uses them.
Final Statement
What can be done in the thread:
1. functions such as setTimeout (), clearTimeout (), setInterval (), and clearInterval () can be used.
2. the navigator object can be used.
3. XMLHttpRequest can be used to send requests.
4. Web Storage can be used in the process.
5. The thread can use self to obtain the scope of the thread.
Something that cannot be done in the thread:
1. DOM/BOM objects other than navigator cannot be used in the thread, such as window and document (messages can only be sent to the worker creator to be operated through the callback function ).
2. Variables and functions in the main thread cannot be used in the thread.
3. Operation commands with "pending" effect, such as alert, cannot be used in the thread.
4. JS cannot be loaded across domains in the thread.
The thread also consumes resources, and the use of the thread will also bring a certain degree of complexity, so if there is no good reason to use the extra thread, then do not use it.
Practical reference
Official documents: http://www.whatwg.org/specs/web-apps/current-work/multipage/workers.html
WebWorker classification Description: http://www.w3schools.com/html5/html5_webworkers.asp
Feet home: http://www.jb51.net/w3school/html5/
WebWorker Overview: https://developer.mozilla.org/en/Using_web_workers