Home  >  Article  >  Web Front-end  >  HTML5 Web Worker usage example tutorial

HTML5 Web Worker usage example tutorial

小云云
小云云Original
2018-01-08 11:20:411567browse

Web Worker is a javascript multi-threading solution provided by HTML5. We can run some computationally intensive codes by web Worker without freezing the user interface. This article mainly introduces the use of HTML5 Web Worker. The editor thinks it is quite good. Now I will share it with you and give you a reference. Let’s follow the editor to take a look, I hope it can help everyone.

1: How to use Worker

The basic principle of Web Worker is to use the Worker class to load a javascript file to open a new thread in the current main thread of javascript. , achieves 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.js
onmessage =function (evt){
  var d = evt.data;//通过evt.data获得发送来的数据
  postMessage( d );//将获取到的数据发送会主线程
}

HTML page: test.html


<!DOCTYPE HTML>
<html>
<head>
 <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
 <script type="text/javascript">
//WEB页主线程
var worker =new Worker("worker.js"); //创建一个Worker对象并向它传递将在新线程中执行的脚本的URL
 worker.postMessage("hello world");     //向worker发送数据
 worker.onmessage =function(evt){     //接收worker传过来的数据函数
   console.log(evt.data);              //输出worker发送来的数据
 }
 </script>
 </head>
 <body></body>
</html>

After opening test.html with Chrome browser, the console output "hello world" indicates that the program execution is successful.

Through this example we can see that using web workers is mainly divided into the following parts

WEB main thread:

1. Load a worker through worker = new Worker(url) JS file 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.

Worker new 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 can it help us solve those problems. Let's look at an example of the fibonacci sequence.

We all know that in mathematics, the fibonacci sequence is defined recursively: F0=0, F1=1, Fn=F(n-1)+F(n-2) (n>=2, n∈N*), and the common implementation of javascript is:


var fibonacci =function(n) {
    return n <2? n : arguments.callee(n -1) + arguments.callee(n -2);
};
//fibonacci(36)

Using this method in chrome to perform the 39 fibonacci sequence execution time is 19097 milliseconds, and to calculate 40 When 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 the example specifically:


//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>
<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(&#39;fibonacci.js&#39;);  
      worker.addEventListener(&#39;message&#39;, function(event) {
        var timer2 = (new Date()).valueOf();
           console.log( &#39;结果:&#39;+event.data, &#39;时间:&#39;+ timer2, &#39;用时:&#39;+ ( timer2  - timer ) );
      }, false);
      var timer = (new Date()).valueOf();
      console.log(&#39;开始计算:40&#39;,&#39;时间:&#39;+ timer );
      setTimeout(function(){
          console.log(&#39;定时器函数在计算数列时执行了&#39;, &#39;时间:&#39;+ (new Date()).valueOf() );
      },1000);
      worker.postMessage(40);
      console.log(&#39;我在计算数列的时候执行了&#39;, &#39;时间:&#39;+ (new Date()).valueOf() );
  }  
  </script>
</head>
<body>
</body>
</html>

Open fibonacci.html in Chrome, The console gets the following output:

Start calculation: 40 Time: 1316508212705
I executed the time when calculating the sequence: 1316508212734
The timer function executed time 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 will not affect the code execution of the main thread. It is completely calculated in its own independent thread, only in After the calculation is completed, the results are sent back to the main thread.

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 web workers to calculate pixels in the scene. When the scene is opened, it is drawn one by one, and one worker only calculates one pixel value.

3: Other attempts of Worker

We already know that Worker creates a worker by receiving a URL, so can we use web worker to do something similar to jsonp As for requests, everyone knows that jsonp loads json data by inserting script tags, and script elements are blocking during loading and execution. It would be very good if web workers can 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.js
function $E(id) {
    return document.getElementById(id);
}
onload =function() {
    //通过web worker加载
    $E(&#39;workerLoad&#39;).onclick =function() {
        var url =&#39;http://js.wcdn.cn/aj/mblog/face2&#39;;
        var d = (new Date()).valueOf();
        var worker =new Worker(url);
        worker.onmessage =function(obj) {
            console.log(&#39;web worker: &#39;+ ((new Date()).valueOf() - d));
        };
    };
    //通过jsonp加载
    $E(&#39;jsonpLoad&#39;).onclick =function() {
        var url =&#39;http://js.wcdn.cn/aj/mblog/face1&#39;;
        var d = (new Date()).valueOf();
        STK.core.io.scriptLoader({
            method:&#39;post&#39;,
            url : url,
            onComplete : function() {
                console.log(&#39;jsonp: &#39;+ ((new Date()).valueOf() - d));
            }
        });
    };
    //通过ajax加载
    $E(&#39;ajaxLoad&#39;).onclick =function() {
        var url =&#39;http://js.wcdn.cn/aj/mblog/face&#39;;
        var d = (new Date()).valueOf();
        STK.core.io.ajax({
            url : url,
            onComplete : function(json) {
                console.log(&#39;ajax: &#39;+ ((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加载"></input>
    <input type="button" id="jsonpLoad" value="jsonp加载"></input>
    <input type="button" id="ajaxLoad" value="ajax加载"></input>
</body>
</html>

Set HOST

127.0.0.1 js.wcdn.cn

via http:/ /js.wcdn.cn/aj/webWorker/worker.html Visit the page and load the data in three ways to get the console output:


web worker: 174
jsonp: 25
ajax: 38

Try a few more times It is found that the time of 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 Worker Initializing new threads takes time. 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 loading" loading button There is no response under Chrome, and an error is prompted under FF6. 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.

So web worker 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: Summary

Web worker looks beautiful, but it is full of devils.

What we can do:

1. 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 the request

5. Can access some properties of the navigator

What are the limitations:

1. Cannot load JS across domains

2. The code in the worker cannot access the DOM

3. The implementation of Worker is inconsistent among various browsers. For example, FF allows the creation of new workers in workers, but not Chrome

4. No Every browser supports this new feature

Related recommendations:

How to implement multi-threading in H5 Web Worker

WebWorkers-front-end high-performance computing

PHP socket server framework workerman

The above is the detailed content of HTML5 Web Worker usage example tutorial. For more information, please follow other related articles on the PHP Chinese website!

Statement:
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