之前你們都認爲js是單線程執行的,假如咱們要執行一些耗時的操做,好比加載一張很大的圖片,咱們可能須要一個進度條來讓用戶進行等待,在等待的過程當中,整個js線程會被阻塞,後面的代碼不能正常運行,這可能大大的下降用戶體驗,這時候咱們就指望擁有一個工做線程來處理這些耗時的操做。在傳統的html時代是基本不可能實現的,而如今,咱們擁有一種叫作worker的東西。它是js裏的一個類,而咱們只須要建立它的實例就可使用它。javascript
1 var worker = new Worker(js file path);
構造函數的參數填上你的js文件的路徑,這個js文件將會在瀏覽器新開的線程裏運行,而與原先的js引擎的線程並不影響。html
下面看個例子java
1 <!DOCTYPE html> 2 <html> 3 <head> 4 <meta charset="utf-8" /> 5 <title></title> 6 </head> 7 <body> 8 <input type="text" name="ipt" id="ipt" value="" /> 9 <button id="start">start</button> 10 <button id="stop">stop</button> 11 <button id="ale">alert</button> 12 <script type="text/javascript"> 13 var ipt = document.getElementById("ipt"); 14 var stop = document.getElementById("stop"); 15 var start = document.getElementById("start"); 16 var ale = document.getElementById("ale"); 17 var worker = new Worker("js/test22.js"); 18 worker.onmessage = function(){ 19 ipt.value = event.data; 20 }; 21 stop.addEventListener("click",function(){ 22 //用於關閉worker線程 23 worker.terminate(); 24 }); 25 start.addEventListener("click",function(){ 26 //開起worker線程 27 worker = new Worker("js/test22.js"); 28 }); 29 ale.addEventListener("click",function(){ 30 alert("i'm a dialog"); 31 }); 32 </script> 33 </body> 34 </html>
下面是test22.js裏的代碼,也就是存在於worker線程裏的代碼瀏覽器
1 var i = 0; 2 function mainFunc(){ 3 i++; 4 //把i發送到瀏覽器的js引擎線程裏 5 postMessage(i); 6 } 7 var id = setInterval(mainFunc,1000);
運行起來咱們會發現函數
點擊肯定後,它的數值並不是2,而是一個比2更大的數post
雖然dialog的彈出會阻塞js引擎線程,可是並不影響worker線程的運行,因此,在咱們點擊肯定後,只是在js引擎線程上更新了新的內容,而數值是一直在跑動的,這就說明worker線程和本來的js線程互不影響.spa
那麼既然互不影響,兩個線程之間要怎麼來聯繫呢,答案其實已經在代碼裏了,那就是onPostMessage 和 onmessage這兩個函數,其中onPostMessage(data)的參數是你要傳遞的數據,而onmessage是一個回調函數,只有在接受到數據時,onmessage會被回調,onmessage有一個隱藏的參數,那就是event,咱們能夠用event.data獲取到傳遞過來的數據來更新主線程。線程
使用worker線程應注意的是,全部js裏集成的對象都在js線程裏,而並不是worker線程。
例如咱們在worker線程裏寫上:code
1 var a = document.getElementById("a");
結果你會獲得一條Error,告訴你找不到document,或者document is undefined。因此咱們儘可能把須要的東西都寫到主線程裏,而只把耗時的操做寫到worker線程裏。htm