讀古今文學網 > 編寫高質量代碼:改善JavaScript程序的188個建議 > 建議182:使用Web Worker >

建議182:使用Web Worker

隨著HTML 5的流行,當JavaScript工作線程對Ajax應用是一個比較迫切的實現要求時,Web Worker得到更多瀏覽器的支持,從而可以在Ajax應用中得到更多的使用。對於Ajax應用開發者來說,必須緊跟HTML 5標準的發展潮流。

WHATAG工作組借鑒了Google Gears的成功經驗,創建了Web Worker規範,並將其作為HTML 5標準的一部分。Web Worker規範定義了一套API,允許Web應用創建在後台執行JavaScript代碼的工作線程。工作線程在執行過程中不會對主頁面造成影響。

在Web Worker規範中定義了兩類工作線程,分別是專屬工作線程和共享工作線程。專屬工作線程只能為一個頁面所使用,而共享工作線程則可以被多個頁面所共享。通過Worker構造方法可以創建一個新的專屬工作線程,在創建時要指定需要執行的JavaScript文件的URL。Web Worker規範並不支持從JavaScript代碼文本中直接創建工作線程。創建工作線程的頁面和工作線程之間通過簡單的消息傳遞來進行交互。通過工作線程對象的postMessage方法就可以發送消息給工作線程,而通過onmessage屬性就可以設置接收到消息時的處理方法。在工作線程的JavaScript代碼中做法也是相同的。例如,下面給出了使用Web Worker計算質數個數的實現方法。

(1)使用專屬工作線程的主頁面代碼


var worker=new Worker("prime_worker.js");

worker.onmessage=function(event){

var result=event.data;

alert("計算完成,質數個數為:"+result);

};

function calculate{

var limit=parseInt(document.getElementById("limit").value)||100000;

worker.postMessage(limit);

}


在主頁面中創建了一個專屬工作線程,讓它在後台執行JavaScript文件prime_worker.js。下面給出在prime_worker.js中與主頁面通信部分的代碼。

(2)專屬工作線程所執行的JavaScript代碼


onmessage=function(event){

var limit=event.data;

var count=calculateNormal(limit);

postMessage(count);

}


共享工作線程的使用方式與專屬工作線程有所不同。共享工作線程允許多個頁面共享使用,每個頁面都是連接到該共享工作線程的某個端口(port)上,頁面通過此端口與共享工作線程進行通信。使用SharedWorker構造方法可以創建出共享工作線程的實例。在發送消息時,需要使用的是工作線程的port對象。下面是使用共享工作線程的主頁面代碼:


var worker=new SharedWorker("prime_worker.js");

worker.port.onmessage=function(event){

var result=event.data;

alert("計算完成,質數個數為:"+result);

};

function calculate{

var limit=parseInt(document.getElementById("limit").value)||100000;

worker.port.postMessage(limit);

}


在共享工作線程所執行的JavaScript代碼中,不能使用onmessage來直接定義接收到消息時的處理方法,而需要使用onconnect來定義接收到連接時的處理邏輯。

(3)共享工作線程所執行的JavaScript代碼


onconnect=function(event){

var port=event.ports[0];

port.onmessage=function(event){

var limit=event.data;

var count=calculateNormal(limit);

port.postMessage(count);

};

}


如上所示,在onconnect的處理方法中,設置了當從某個端口上接收到消息時應該執行的處理邏輯。

除了通過onmessage屬性來設置消息處理方法之外,還可以使用addEventListener來添加消息處理方法,這樣做的好處是可以添加多個事件處理方法。需要注意的是,如果使用addEventListener來添加事件處理方法,在添加完成之後,需要調用port.start方法來顯式地啟動端口上的通信。

Web Worker目前只有一些較新的瀏覽器上支持Web Worker,如Firefox 3.5、Safari 4、Google Chrome 4和Opera 10.6等以及它們的更高版本。由於IE的主流版本不支持Web Worker,使用Web Worker編寫的Web應用是不能在IE上運行的。