在 Html5 中提出了工作線程(Web Workers)的概念,即多線程概念,可以將一些大量計算的代碼交給web worker運行而不凍結用戶界面。
Web Workers 的三大主要特征:
1)能夠長時間運行(響應)
2)理想的啟動性能
3)理想的內存消耗
Web Workers 允許開發人員編寫能夠長時間運行而不被用戶所中斷的後台程序,去執行事務或者邏輯,並同時保證頁面對用戶的及時響應。
Web Workers 為 Web 前端網頁上的腳本提供了一種能在後台進程中運行的方法。一旦它被創建,Web Workers 就可以通過 postMessage 向任務池發送任務請求,執行完之後再通過 postMessage 返回消息給創建者指定的事件處理程序 ( 通過 onmessage 進行捕獲 )。Web Workers 進程能夠在不影響用戶界面的情況下處理任務,並且,它還可以使用 XMLHttpRequest 來處理 I/O,但通常,後台進程(包括 Web Workers 進程)不能對 DOM 進行操作。如果希望後台程序處理的結果能夠改變 DOM,只能通過返回消息給創建者的回調函數進行處理。
需要在客戶端頁面的 JavaScript 代碼中 new 一個 Worker 實例出來,參數是需要在另一個線程中運行的 Javascript 文件名稱。然後在這個實例上監聽 onmessage 事件。最後另一個線程中的 JavaScript 就可以通過調用 postMessage 方法在這兩個線程間傳遞數據了。
主程序中,創建worker實例,監聽onmessage事件
<Html>
<head>
<meta http-equiv="Content-Type" content="text/Html; charset=UTF-8">
<title>Test Web worker</title>
<script type="text/JavaScript">
function init(){
var worker = new Worker('compute.JS');
//event 參數中有 data 屬性,就是子線程中返回的結果數據
worker.onmessage= function (event) {
// 把子線程返回的結果添加到 div 上
document.getElementById("result").innerHtml +=
event.data+"<br/>";
};
}
</script>
</head>
<body onload="init()">
<div id="result"></div>
</body>
</Html>
在客戶端的 compute.JS 開辟了一個新的線程,不起阻塞執行的效果,並且提供主線程和新線程之間的數據交互接口。只是簡單的重復多次加和操作,最後通過 postMessage 方法把結果返回給主線程,目的就是等待一段時間。而在這段時間內,主線程不應該被阻塞,用戶可以通過拖拽浏覽器,變大縮小浏覽器窗口等操作測試這一現象。這個非阻塞主線程的結果就是 Web Workers 想達到的目的。
compute.JS 中調用 postMessage 方法返回計算結果
var i=0;
function timedCount(){
for(var j=0,sum=0;j<100;j++){
for(var i=0;i<1000000;i++){
sum+=i;
}
}
// 調用 postMessage 向主線程發送消息
postMessage(sum);
}
postMessage("獲取計算之前的時間,"+new Date());
timedCount();
postMessage("獲取計算之後的時間,"+new Date());
演示地址:http://lovermap.sinaapp.com/test/test.Html
由於Javascript是單線程執行的,在復雜地運算的過程中浏覽器不能執行其它Javascript腳本,UI渲染線程也會被掛起,從而導致浏覽器進入僵死狀態。使用web worker將數列的計算過程放入一個新線程裡去執行將避免這種情況的出現。
除了可以使用web worker加載一個JS進行大量的復雜計算而不掛起主進程,並通過postMessage,onmessage進行通信外;可以在worker中通過importScripts(url)加載另外的腳本文件,使用 setTimeout(), clearTimeout(), setInterval(), and clearInterval(),使用XMLHttpRequest來發送請求,訪問navigator的部分屬性。
但是也是存在一定的局限性:
1.不能跨域加載JS(同源策略限制)
2.worker內代碼不能訪問DOM
3.各個浏覽器對Worker的實現不大一致
4.不是每個浏覽器都支持這個新特性