Web Worker is a javascript multi-threading solution provided by HTML5. We can hand over some computationally intensive code to the web worker to run without freezing the user interface.
1: How to use WorkerThe basic principle of Web Worker is to use the Worker class to load a JavaScript file in the current main thread of JavaScript to open a new thread, which has the effect of non-blocking execution 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.jsonmessage =function (evt){ var d = evt.data;//Get the sent data through evt.data postMessage(d);//Send the obtained data to the main thread}HTML page: test.html
<!DOCTYPE HTML><html><head> <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); //Create a Worker object and pass it the URL of the script that will be executed in the new thread worker.postMessage(hello world); //Send data to the worker worker.onmessage =function(evt){ //Receive the data function console.log(evt.data) from the worker; //Output the data sent from the worker} </script> </head> <body></body></ html>After opening test.html with the Chrome browser, the console outputs hello world, indicating that the program is executed successfully.
From this example we can see that using web workers is mainly divided into the following parts:
WEB main thread:
1. Load a JS file through worker = new Worker( url ) to create a worker and return a worker instance.
2. Send data to the worker through the worker.postMessage(data) method.
3. Bind the worker.onmessage method to receive the data sent by the worker.
4. You can use worker.terminate() to terminate the execution of a worker.
new worker thread:
1. Send data to the main thread through the postMessage(data) method.
2. Bind the onmessage method to receive the data sent by the main thread.
2: What can Worker do?Now that we know how to use web worker, what is its use and what problems can it help us solve. Let's look at an example of the fibonacci sequence.
As we all know, in mathematics, the fibonacci sequence is defined recursively: F0=0, F1=1, Fn=F(n-1)+F(n-2) (n>=2, n∈N*), The common implementation of javascript is:
var fibonacci =function(n) { return n <2? n : arguments.callee(n -1) + arguments.callee(n -2);};//fibonacci(36)The execution time of using this method to calculate the fibonacci sequence of 39 in Chrome is 19097 milliseconds, but when it comes to calculating 40, the browser directly prompts that the script is busy.
Since JavaScript is executed in a single thread, the browser cannot execute other JavaScript scripts during the process of calculating the sequence, and the UI rendering thread will also be suspended, causing the browser to enter a zombie state. Using a web worker to put the calculation process of the sequence into a new thread will avoid this situation. See specific examples:
//fibonacci.jsvar 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><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('fibonacci.js'); worker.addEventListener('message', function(event) { var timer2 = (new Date()).valueOf(); console.log( 'Result:'+event.data, 'Time:'+ timer2, 'Time taken:'+ ( timer2 - timer ) ); }, false); var timer = ( new Date()).valueOf(); console.log('Start calculation: 40', 'Time:' + timer ); setTimeout(function(){ console.log('The timer function was executed when calculating the sequence', 'Time:'+ (new Date()).valueOf() ); },1000); worker.postMessage(40); console.log(' I executed ', 'time:'+ (new Date()).valueOf() ); } </script></head><body></body></html> when calculating the sequenceOpen fibonacci.html in Chrome, and the console gets the following output:
Start counting: 40 Time: 1316508212705
When I calculated the sequence, I executed the time: 1316508212734
The timer function executed when calculating the sequence: 1316508213735
Result: 102334155 Time: 1316508262820 Elapsed time: 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 completely calculated in its own independent thread, and the results are only sent back to the main thread after the calculation is completed.
Using web workers, we can perform some complex and large-scale operations on the front end without affecting the display of the page, and the disgusting script busy prompt will not pop up.
The following example uses a web worker to calculate pixels in the scene. When the scene is opened, it is drawn one by one. A worker only calculates one pixel value.
Three: Other attempts by WorkerWe already know that Worker creates a worker by receiving a URL, so can we use web workers to make some requests similar to jsonp? As we all know, jsonp loads json data by inserting script tags, and the script element is loading and executing The process is all blocking. It would be great if web workers could be used to implement asynchronous loading.
The following example will load a 169.42KB JSON data through three different methods: web worker, jsonp, and ajax.
// /aj/webWorker/core.jsfunction $E(id) { return document.getElementById(id);}onload =function() { //Load through 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 through 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)); } }); }; //Load $E('ajaxLoad') through ajax.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><html><head><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></head><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></html>
Set up HOST
127.0.0.1 js.wcdn.cn
Access the page through http://js.wcdn.cn/aj/webWorker/worker.html and then load the data in three ways to get the console output:
web worker: 174jsonp: 25ajax: 38
After trying several times, I found that the time difference between loading data through jsonp and ajax is not much different, and the loading time of web worker is always at a high level, so using web worker to load data is still relatively slow, even in the case of large data volume, there is no advantage. , it may be that it takes time for Worker to initialize new threads. There is no advantage other than being non-blocking during loading.
So can web worker support cross-domain js loading? This time we access the page through http://127.0.0.1/aj/webWorker/worker.html. When clicking the web worker load button, nothing is reflected in Chrome. FF6 The following error message appears. From this we can know that web worker does not support cross-domain loading of JS, which is bad news for websites that deploy static files to a separate static server.
Therefore, web workers can only be used to load json data in the same domain, and ajax can already do this, and it is more efficient and versatile. Let the Worker do what it is good at.
Four: SummaryWeb workers look great, but they are devilish.
What we can do:
1. You can load a JS to perform a large number of complex calculations without hanging the main process, and communicate through postMessage, onmessage
2. You can load additional script files in the worker through importScripts(url)
3. You can use setTimeout(), clearTimeout(), setInterval(), and clearInterval()
4. You can use XMLHttpRequest to send requests
5. Can access some properties of navigator
What are the limitations:
1.Cannot load JS across domains
2. The code within the worker cannot access the DOM
3. Various browsers have different implementations of Worker. For example, FF allows the creation of new workers in workers, but Chrome does not.
4. Not every browser supports this new feature
The above is the entire content of this article. I hope it will be helpful to everyone’s study. I also hope everyone will support VeVb Wulin Network.