Web Workers is a JavaScript multithreaded solution provided by HTML5, and we can leave some large computational amounts of code to the Web worker to run without freezing the user interface.
One: How to use worker
The basic principle of WEB worker is that in the main thread of the current JavaScript, the worker class is used to load a JavaScript file to open up a new thread that does not block the execution of the effect. and provides an interface for data exchange between the main thread and the new thread: Postmessage,onmessage.
So how to use it, let's look at an example:
Worker.js
OnMessage =function (evt) {
var d = evt.data;//data sent via Evt.data
PostMessage (d);//will get the data sent to the main thread
}
HTML page: test.html
<! DOCTYPE html>
<meta http-equiv= "Content-type" content= "text/html; Charset=utf-8 "/>
<script type= "Text/javascript" >
Web page main thread
var worker =new worker ("Worker.js"); Creates a worker object and passes it the URL of the script that will execute in the new thread
Worker.postmessage ("Hello World"); Send data to Worker
Worker.onmessage =function (evt) { //Receiving worker passed data function
Console.log (evt.data); Output data sent by worker
}
</script>
<body></body>
After opening test.html in Chrome, the console output "Hello World" indicates that the program executed successfully.
In this example, we can see that the use of web workers is mainly divided into the following parts
Web Main thread:
1. Load a JS file with the worker = new Worker (URL) to create a worker and return a worker instance.
2. Use the Worker.postmessage (data) method to send data to the worker.
3. Bind the Worker.onmessage method to receive data sent by the worker.
4. You can use Worker.terminate () to terminate the execution of a worker.
Worker New Thread:
1. Use the PostMessage (data) method to send data to the main thread.
2. Bind the OnMessage method to receive the data sent by the mainline Cheng.
II: What the worker can do
Knowing how to use Web worker, what is the use of it, can help us solve those problems. Let's look at an example of a Fibonacci sequence.
As you know mathematically, the Fibonacci sequence is defined recursively: f0=0,f1=1,fn=f (n-1) +f (n-2), while JavaScript's common implementations are:
var Fibonacci =function (N) {
return n <2? N:arguments.callee (n-1) + Arguments.callee (n-2);
};
Fibonacci (36)
In Chrome, 39 of the Fibonacci sequence execution time is 19097 milliseconds, and the browser prompts the script to be busy when the 40 is calculated.
Because JavaScript is a single-threaded execution, the browser cannot execute other JavaScript scripts during the sequence, and the UI render thread is suspended, causing the browser to enter a zombie state. Using a web worker to put the calculation of a sequence into a new thread to do this will prevent this from happening. See the example in detail:
Fibonacci.js
var Fibonacci =function (N) {
return n <2? N:arguments.callee (n-1) + Arguments.callee (n-2);
};
OnMessage =function (Event) {
var n = parseint (Event.data, 10);
PostMessage (Fibonacci (n));
};
HTML page: fibonacci.html
<! DOCTYPE html>
<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 (' fibonacci.js ');
Worker.addeventlistener (' message ', function (event) {
var timer2 = (new Date ()). ValueOf ();
Console.log (' Result: ' +event.data, ' time: ' + timer2, ' spents: ' + (Timer2-timer));
}, False);
var timer = (new Date ()). ValueOf ();
Console.log (' Start calculation: 40 ', ' time: ' + timer); The
SetTimeout (function () {
Console.log (' timer function ' executes ' at the time of the calculation of the sequence ', ' "": ' + (new Date ()) '). ValueOf ());
},1000);
Worker.postmessage (40);
Console.log (' I performed ' at the time of the calculation of the series ', ' Time: ' + (new Date ()). ValueOf ());
}
</script>
<body>
</body>
Open fibonacci.html in Chrome and the console gets the following output:
Start calculation: 40 Time: 1316508212705
I'm doing it when I'm calculating the sequence. Time: 1316508212734
The timer function executes when calculating a sequence: 1316508213735
Results: 102334155 time: 1316508262820 spents: 50115
This example shows that the calculation of the Fibonacci sequence performed in the worker does not affect the code execution of the main thread, it is calculated entirely in its own separate thread, but sends the result back to the main thread after the calculation is complete.
With web worker we can perform a number of complex operations on the front end without affecting the presentation of the page, and will not pop up the nasty script that is busy prompting.
The following example uses a web worker to calculate the pixels in the scene, and the scene is opened with a piece of paint, and a worker calculates only one pixel value.
Http://nerget.com/rayjs-mt/rayjs.html
III: Other attempts by the worker
We already know that the worker creates a worker by receiving a URL, so can we use the Web worker to do something like JSONP, and you know that JSONP is loading JSON data by inserting a script tag, While the script element is blocked during loading and execution, it would be nice to use Web worker to implement asynchronous loading.
The following example loads a 169.42KB-size JSON data in three different ways by web worker, Jsonp, Ajax
/aj/webworker/core.js
function $E (ID) {
return document.getElementById (ID);
}
OnLoad =function () {
Loading via web worker
$E (' Workerload '). OnClick =function () {
var url = ' Http://js.wcdn.cn/aj/mblog/face2 ';
var d = (new Date ()). ValueOf ();
var worker =new worker (URL);
Worker.onmessage =function (obj) {
Console.log (' Web worker: ' + ((new Date ()). ValueOf ()-D));
};
};
Load via JSONP
$E (' Jsonpload '). OnClick =function () {
var url = ' Http://js.wcdn.cn/aj/mblog/face1 ';
var d = (new Date ()). ValueOf ();
STK.core.io.scriptLoader ({
Method: ' Post ',
Url:url,
Oncomplete:function () {
Console.log (' Jsonp: ' + ((new Date ()). ValueOf ()-D));
}
});
};
Loading via Ajax
$E (' Ajaxload '). OnClick =function () {
var url = ' Http://js.wcdn.cn/aj/mblog/face ';
var d = (new Date ()). ValueOf ();
STK.core.io.ajax ({
Url:url,
Oncomplete:function (JSON) {
Console.log (' Ajax: ' + ((new Date ()). ValueOf ()-D));
}
});
};
};
HTML page:/aj/webworker/worker.html
<! DOCTYPE html>
<meta http-equiv= "Content-type" content= "text/html; Charset=utf-8 "/>
<title>worker Example:load data</title>
<script src= "Http://js.t.sinajs.cn/STK/js/gaea.1.14.js" type= "Text/javascript" ></script>
<script type= "Text/javascript" src= "Http://js.wcdn.cn/aj/webWorker/core.js" ></script>
<body>
<input type= "button" id= "Workerload" value= "web worker Load" ></input>
<input type= "button" id= "Jsonpload" value= "Jsonp load" ></input>
<input type= "button" id= "Ajaxload" value= "Ajax Load" ></input>
</body>
Set host
127.0.0.1 js.wcdn.cn
Access the page via http://js.wcdn.cn/aj/webWorker/worker.html and load the data in three different ways to get console output:
Web worker:174
Jsonp:25
ajax:38
Try to find the time to load data through JSONP and Ajax is not small, and the load time of the Web worker is always high, so the Web worker to load the data is still relatively slow, even if the large data volume without any advantage, It is possible that the worker initializes the new thread for the time elapsed. There is no advantage in addition to being non-blocking during the loading process.
So whether the Web worker can support cross-domain JS loading, this time we access the page through http://127.0.0.1/aj/webWorker/worker.html, when the "Web Worker Loading" button is clicked, Chrome has no reflection , FF6 prompt error. As a result, we know that Web worker does not support cross-domain loading JS, which is bad news for sites that deploy static files to a separate static server.
So web worker can only be used to load JSON data under the same domain, and Ajax can be done and more efficient and general. Let the worker do what it is good at.
Four: summary
Web workers look beautiful, but the devil is everywhere.
What we can do:
1. Can load a JS for a large number of complex computations without suspending the main process and communicating via Postmessage,onmessage
2. Additional script files can be loaded in worker via Importscripts (URL)
3. Can use SetTimeout (), cleartimeout (), SetInterval (), and Clearinterval ()
4. You can use XMLHttpRequest to send requests
5. Can access some properties of Navigator
There are those limitations:
1. Cannot load JS across domains
2.worker inside code cannot access DOM
3. Individual browsers do not agree with worker implementations, such as allowing new workers to be created in the FF, but not in chrome
4. Not every browser supports this new feature
HTML5 Web worker Simple to use