HTML5 Web Worker簡單使用

來源:互聯網
上載者:User

標籤:插入   javascrip   text   頁面   add   example   計算過程   遞迴   設定   

Web Workers 是 HTML5 提供的一個javascript多線程解決方案,我們可以將一些大計算量的代碼交由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(‘fibonacci.js‘);
worker.addEventListener(‘message‘, function(event) {
var timer2 = (new Date()).valueOf();
console.log( ‘結果:‘+event.data, ‘時間:‘+ timer2, ‘用時:‘+ ( timer2 - timer ) );
}, false);
var timer = (new Date()).valueOf();
console.log(‘開始計算:40‘,‘時間:‘+ timer );
setTimeout(function(){
console.log(‘定時器函數在計算數列時執行了‘, ‘時間:‘+ (new Date()).valueOf() );
},1000);
worker.postMessage(40);
console.log(‘我在計算數列的時候執行了‘, ‘時間:‘+ (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只計算一塊像素值。

http://nerget.com/rayjs-mt/rayjs.html

三: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(‘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));
};
};
//通過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));
}
});
};
//通過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頁面:/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.不是每個瀏覽器都支援這個新特性

HTML5 Web Worker簡單使用

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.