首頁 web前端 css教學 HTML5 Web Worker的使用實例教學

HTML5 Web Worker的使用實例教學

Jan 08, 2018 am 11:20 AM
html5 web worker

Web Worker是HTML5提供的一個javascript多執行緒解決方案,我們可以將一些大運算量的程式碼交由web Worker運行而不凍結使用者介面。本文主要介紹了淺談HTML5 Web Worker的使用,小編覺得挺不錯的,現在分享給大家,也給大家做個參考。一起跟著小編過來看看吧,希望能幫助大家。

一:如何使用Worker

Web Worker的基本原理就是在目前javascript的主執行緒中,使用Worker類別來載入一個javascript檔來開啟一個新的執行緒,起到互不阻塞執行的效果,並且提供主線程和新線程之間資料交換的介面:postMessage,onmessage。

那麼要如何使用呢,我們看一個例子:


//worker.js
onmessage =function (evt){
  var d = evt.data;//通过evt.data获得发送来的数据
  postMessage( d );//将获取到的数据发送会主线程
}
登入後複製

HTML頁面: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>
登入後複製

用Chrome瀏覽器開啟test.html後,控制台輸出  "hello world" 表示程式執行成功。

透過這個例子我們可以看出使用web worker主要分成以下幾部分

WEB主執行緒:

1.透過worker = new Worker( url ) 載入一個JS檔案來建立一個worker,同時傳回一個worker實例。

2.透過worker.postMessage( data ) 方法來傳送資料給worker。

3.綁定worker.onmessage方法來接收worker傳送過來的資料。

4.可以使用 worker.terminate() 來終止一個worker的執行。

worker新執行緒:

1.透過postMessage( data ) 方法來傳送資料到主執行緒。

2.綁定onmessage方法來接收主執行緒傳送過來的資料。

二:Worker能做什麼

知道如何使用web worker ,那麼它到底有什麼用,可以幫我們解決那些問題呢。我們來看一個fibonacci數列的例子。

大家知道在數學上,fibonacci數列被以遞歸的方法定義:F0=0,F1=1,Fn=F(n-1)+F(n-2)(n>=2, n∈N*),而javascript的常用實作為: 


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

在chrome中用該方法進行39的fibonacci數列執行時間為19097毫秒,而要計算40的時候瀏覽器直接提示腳本忙了。

由於javascript是單執行緒執行的,在求數列的過程中瀏覽器不能執行其它javascript腳本,UI渲染執行緒也會被掛起,導致瀏覽器進入僵死狀態。使用web worker將數列的計算過程放入一個新執行緒裡去執行將避免這種情況的出現。具體看範例:


//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頁面: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>
登入後複製

在Chrome中開啟fibonacci.html,控制台得到如下輸出:

開始計算:40 時間:1316508212705

我在計算數列的時候執行了時間:1316508212734
定時器函數在計算數列時執行了時間:1316508213735
結果:102334155 時間:1316508262820 用時:50115

這個例子說明在worker中執行的fibonacci數列的計算並不會影響到主線程的程式碼執行,完全在自己獨立的線程中計算,只是在自己獨立的執行緒中計算,只是在自己獨立的執行緒中計算計算完成之後將結果發回主執行緒。

利用web worker我們可以在前端執行一些複雜的大量運算而不會影響頁面的展示,並且不會彈出噁心的腳本正忙提示。

下面這個範例使用了web worker來計算場景中的像素,場景開啟時是一片一片進行繪製的,一個worker只計算一塊像素值。

三:Worker的其他嘗試

我們已經知道Worker透過接收一個URL來創建一個worker,那麼我們是否可以利用web worker來做一些類似jsonp的請求呢,大家知道jsonp是透過插入script標籤來載入json資料的,而script元素在載入和執行過程中都是阻塞式的,如果能利用web worker實現非同步載入將會非常好。

下面這個範例將透過web worker、jsonp、ajax三種不同的方式來載入一個169.42KB大小的JSON資料


// /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頁面: /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>
登入後複製

設定HOST

127.0.0.1 js.wcdn.cn

透過http:/ /js.wcdn.cn/aj/webWorker/worker.html 存取頁面然後分別透過三種方式載入數據,得到控制台輸出:


web worker: 174
jsonp: 25
ajax: 38
登入後複製
多試幾次發現透過jsonp和ajax載入資料的時間相差不大,而web worker的載入時間一直處於高位,所以用web worker來載入資料還是比較慢的,即便是大資料量情況下也沒任何優勢,可能是Worker初始化新起執行緒比較耗時。除了在加載過程中是無阻塞的之外沒有任何優勢。

那麼web worker是否能支援跨域js載入呢,這次我們透過http://127.0.0.1/aj/webWorker/worker.html 來存取頁面,當點擊"web worker載入" 載入按鈕時Chrome下無任何反映,FF6下提示錯誤。由此我們可以知道web worker是不支援跨網域載入JS的,這對於將靜態檔案部署到單獨的靜態伺服器的網站來說是個壞消息。

所以web worker只能用來載入同域下的json數據,而這方面ajax已經可以做到了,而且效率更高更通用。還是讓Worker做它自己擅長的事吧。

四:總結

web worker看起來很美好,但到處都是魔鬼。

我們可以做什麼:

1.可以載入一個JS進行大量的複雜計算而不掛起主進程,並透過postMessage,onmessage進行通訊

2.可以在worker中透過importScripts(url)載入另外的腳本檔案

3.可以使用setTimeout(), clearTimeout(), setInterval(), and clearInterval()

4.可以使用XMLHttpRequest來傳送請求

#5.可以存取navigator的部分屬性

#有那些限制:

#1.不能跨網域載入JS

##2. worker內程式碼不能存取DOM

3.各個瀏覽器對Worker的實作不大一致,例如FF裡允許worker中創建新的worker,而Chrome中就不行

4.不是每個瀏覽器都支援這個新功能

相關推薦:


H5的多執行緒如何實作Web Worker

WebWorkers-前端的高效能運算

PHP socket 伺服器框架workerman

以上是HTML5 Web Worker的使用實例教學的詳細內容。更多資訊請關注PHP中文網其他相關文章!

本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

Video Face Swap

Video Face Swap

使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱工具

記事本++7.3.1

記事本++7.3.1

好用且免費的程式碼編輯器

SublimeText3漢化版

SublimeText3漢化版

中文版,非常好用

禪工作室 13.0.1

禪工作室 13.0.1

強大的PHP整合開發環境

Dreamweaver CS6

Dreamweaver CS6

視覺化網頁開發工具

SublimeText3 Mac版

SublimeText3 Mac版

神級程式碼編輯軟體(SublimeText3)

HTML 中的表格邊框 HTML 中的表格邊框 Sep 04, 2024 pm 04:49 PM

HTML 表格邊框指南。在這裡,我們以 HTML 中的表格邊框為例,討論定義表格邊框的多種方法。

HTML 中的巢狀表 HTML 中的巢狀表 Sep 04, 2024 pm 04:49 PM

這是 HTML 中巢狀表的指南。這裡我們討論如何在表中建立表格以及對應的範例。

HTML 左邊距 HTML 左邊距 Sep 04, 2024 pm 04:48 PM

HTML 左邊距指南。在這裡,我們討論 HTML margin-left 的簡要概述及其範例及其程式碼實作。

HTML 表格佈局 HTML 表格佈局 Sep 04, 2024 pm 04:54 PM

HTML 表格佈局指南。在這裡,我們詳細討論 HTML 表格佈局的值以及範例和輸出。

HTML 輸入佔位符 HTML 輸入佔位符 Sep 04, 2024 pm 04:54 PM

HTML 輸入佔位符指南。在這裡,我們討論 HTML 輸入佔位符的範例以及程式碼和輸出。

HTML 有序列表 HTML 有序列表 Sep 04, 2024 pm 04:43 PM

HTML 有序列表指南。在這裡我們也分別討論了 HTML 有序列表和類型的介紹以及它們的範例

在 HTML 中移動文字 在 HTML 中移動文字 Sep 04, 2024 pm 04:45 PM

HTML 中的文字移動指南。在這裡我們討論一下marquee標籤如何使用語法和實作範例。

HTML onclick 按鈕 HTML onclick 按鈕 Sep 04, 2024 pm 04:49 PM

HTML onclick 按鈕指南。這裡我們分別討論它們的介紹、工作原理、範例以及各個事件中的onclick事件。

See all articles