今天這篇內容主要講述HTML 5 Web Worker(一種支持前端js多線程的技術)。javascript
W3C 在 HTML5 的規範中提出了工做線程(Web Worker)的概念,工做線程容許開發人員編寫可以長時間運行而不被用戶所中斷的後臺程序, 去執行事務或者邏輯,並同時保證頁面對用戶的及時響應。
工做線程的出現使得在 Web 頁面中進行多線程編程成爲可能。衆所周知,傳統頁面中(HTML5 以前)的 JavaScript 的運行都是以單線程的方式工做的,雖然有多種方式實現了對多線程的模擬(例如:JavaScript 中的 setinterval 方法,setTimeout 方法等),可是在本質上程序的運行仍然是由 JavaScript 引擎以單線程調度的方式進行的。在 HTML5 中引入的工做線程使得瀏覽器端的 JavaScript 引擎能夠併發地執行 JavaScript 代碼,從而實現了對瀏覽器端多線程編程的良好支持。html
Web Worker的基本原理就是在當前javascript的主線程中,使用Worker類加載一個javascript文件來開闢一個新的線程,起到互不阻塞執行的效果,而且提供主線程和新線程之間數據交換的接口:postMessage,onmessage。前端
Web Worker 能夠分爲兩種不一樣線程類型,一個是專用線程 Dedicated Worker,一個是共享線程 Shared Worker。兩種類型的線程各有不一樣的用途。下面僅僅對專用工做線程作簡要描述。
Web worker的運行原理和兩種線程的詳細說明請查看這裏。java
它是專用線程的執行文件,即複雜的運算都在這裏執行,onmessage接收主線程發送來的消息(參數),並將運行結果postMessage回主線程。web
if(typeof(Worker)!=="undefined")
在建立專用線程的時候,須要給 Worker 的構造函數提供一個指向 JavaScript 文件資源的 URL,這也是建立專用線程時 Worker 構造函數所須要的惟一參數。當這個構造函數被調用以後,一個工做線程的實例便會被建立出來。下面是建立專用線程代碼示例:編程
var worker = new Worker(jsrefurl);
worker.onmessage = function (event) { ... };
worker.postMessage();
當咱們建立 web worker 對象後,它會繼續監聽消息(即便在外部腳本完成以後)直到其被終止爲止。
如需終止 web worker,並釋放瀏覽器/計算機資源,請使用 terminate() 方法:瀏覽器
worker.terminate();
下面咱們使用一個示例說明上述過程。多線程
新建外部web worker 的js文件,命名爲webworker.js併發
onmessage = function (event) { var msg = event.data; for (var i = 0 ; i < msg; i++) { if (!!console && i % 500 == 0) { console.info(i); } } var d = new Date(); postMessage(d); }
新建主線程頁面,命名爲webworker.html函數
<!DOCTYPE html> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/> <title></title> </head> <body> web worker實時時間:<div id="workerTime"></div> <br /> 主線程獲取當前時間:<div id="curTime"></div> <button onclick="mainthread()">主線程獲取時間</button> <script> var interval; if (typeof Worker != undefined) { var worker = new Worker("webworker1.js"); worker.onmessage = function (event) { document.getElementById("workerTime").textContent = event.data; } interval = setInterval('worker.postMessage("1000000")', 1000); } function mainthread() { document.getElementById("curTime").textContent = new Date(); } function stop() { clearInterval(interval);
worker.terminate(); } setTimeout(stop, 60000);//60秒以後清理interval </script> </body> </html>
代碼很簡單,只是爲了說明webworker線程不會阻塞主線程(即實現前端多線程)。
示例中咱們將webworker線程設置interval不斷髮起請求,使用一個循環在模仿複雜操做,或者你也能夠在js中加入其餘操做來模擬耗時操做。
定義了一個按鈕,在主線程中獲取當前時間。咱們能夠隨時點擊該按鈕調用主線程的方法,而其不會受到web worker線程的影響。
運行效果我就不貼圖了,各園友粘貼代碼便可運行查看效果。
因爲 web worker 位於外部文件中,它們沒法訪問下列 JavaScript 對象:
本文示例很簡單,可是麻雀雖小五臟俱全。
主線程新建web worker,發送消息及接收消息,web worker 接收及反饋消息,主線程主動中止web worker線程等全都使用到了。
相信看完這個簡介和示例,對web worker也有了必定掌握。