(轉載)WebWorker是什麼鬼?

來源:互聯網
上載者:User

標籤:作用   非同步   而在   將不   另一個   包含   world   凍結   tor   

前言

前端工程師們一定有過這樣的體驗,當一個頁面載入了大量的 js 檔案時,使用者介面可能會短暫地“凍結”。這很好理解,因為 js 是單線程的語言。我們再走的極端點,一段 js 中出現了 while(){} 的死迴圈,這時再去點擊頁面的 DOM 元素,將不會觸發事件,事實上,這些非同步事件都排成了隊列,只等頁面的 js 渲染完後去執行(從setTimeout談JavaScript運行機制),而此時渲染進入了死迴圈,所以出現了使用者介面被“凍結”的現象。

而實際的開發中,雖然不會出現類似的死迴圈,但是大量的 js 渲染還是會影響使用者體驗的,此時我們希望這段耗時的 js 最好能非同步去執行,setTimeout 是一個好的方法,但是 H5 提供了更好的辦法,Web Worker! Web Worker 規範通過讓 Javascript 在後台運行解決了這個問題。瀏覽器實現 Web Worker 規範的方式有很多種,可以使用線程、後台進程或者運行在其他處理器核心上的進程,等等。具體的實現細節其實沒有那麼重要,重要的是開發人員現在可以放心地運行 Javascript,而不必擔心會影響使用者體驗了。

既然 Worker 是 H5 大家庭的,那麼 ie6 之輩就可以一邊去了,詳細的瀏覽器安全色性可以參考 http://caniuse.com/#search=worker

如果沒有 Worker

我們來看這樣一段代碼:

<div style=‘width:100px;height:100px;background-color:red‘></div> <script>   document.querySelector(‘div‘).onclick = function() {     console.log(‘hello world‘);   };    function fibonacci(n) {     return n < 2 ? n : arguments.callee(n - 1) + arguments.callee(n - 2);   }    console.log(fibonacci(36)); </script> 

頁面上寫了一個 div,然後監聽了它的 click 事件,並且在 js 中需要計算斐波那契數列的第 36 項,並將它輸出。這樣的頁面使用者體驗是非常差的,如果 fibonacci 不執行完,div 的 click 事件是無法及時響應的,而遞迴求解斐波那契數列項是相當耗時的!這樣一段耗時的 js 代碼,交給 worker 來做正合適!

祭出大殺器 Worker

Worker 的使用方法很簡單。

執行個體化 Worker 對象並傳入要執行的 Javascript 檔案名稱就可以建立一個新的 Web Worker:

var worker = new Worker(‘worker.js‘); 

這段代碼會導致瀏覽器下載 worker.js,但只有 Worker 接收到訊息才會實際執行檔案中的代碼。要給 Worker 傳遞訊息,可以使用 postMessage() 方法,比如我要告訴 Worker 需要求斐波那契數列的第 36 項:

worker.postMessage(36); 

 我們來看看 Worker 是怎麼接收訊息的。當頁面在 worker 對象上調用 postMessage()時,資料會以非同步方式傳遞給 worker,進而觸發 worker 中的 message 事件。為了處理來自頁面的資料,同樣也要建立一個 onmessage 事件處理常式。(worker.js 代碼)

self.onmessage = function(event) {   var data = event.data;   console.log(fibonacci(data)); };  function fibonacci(n) {   return n < 2 ? n : arguments.callee(n - 1) + arguments.callee(n - 2); } 

頁面可以傳資料給 Worker,Worker 當然也可以回傳,頁面通過 message 事件進行監聽:

worker.onmessage = function(event) {   var data = event.data; }; 

Worker 是通過 message 和 error 事件與頁面通訊的。來自 Worker 的資料儲存在 event.data 中。Worker 不能完成給定的任務時會觸發 error 事件。具體來說,Worker 內部的 Javascript 在執行過程中只要遇到錯誤,就會觸發 error 事件。發生 error 事件時,事件對象中包含三個屬性:filename、lineno 和 message,分別表示錯誤的檔案名稱、程式碼號和完整的錯誤資訊:

worker.onerror = function(event) {   console.log(event.filename, event.lineno, event.message); }; 

我們建議使用 worker 時最好寫上 error 事件,就像使用 ajax 時總要寫上擷取失敗時的補救操作一樣。

完整代碼:

html 檔案:

<div style=‘width:100px;height:100px;background-color:red‘></div> <script>   document.querySelector(‘div‘).onclick = function() {     console.log(‘hello world‘);   };    var worker = new Worker(‘worker.js‘);   worker.postMessage(36);   worker.onmessage = function(event) {     var data = event.data;     console.log(data)   };    worker.onerror = function(event) {     console.log(event.filename, event.lineno, event.message);   }; </script> 

worker.js 檔案:

self.onmessage = function(event) {   var data = event.data;   var ans = fibonacci(data);   this.postMessage(ans); };  function fibonacci(n) {   return n < 2 ? n : arguments.callee(n - 1) + arguments.callee(n - 2); } 

簡單小結:

WEB主線程:

  1. 通過 var worker = new Worker(url) 載入一個 js 檔案來建立一個 worker,同時返回一個 worker 執行個體。
  2. 通過 worker.postMessage(data) 方法來向 worker 發送資料。
  3. 綁定 worker.onmessage 方法來接收 worker 發送過來的資料。
  4. 可以使用 worker.terminate() 來終止一個 worker 的執行。

worker新線程:

  1. 綁定 onmessage 方法來接收主線程發送過來的資料。
  2. 通過 postMessage(data) 方法來向主線程發送資料。
  3. 可以使用 self.close() 來終止一個 worker 的執行。

Worker 其他

關於 Web Worker,最重要的是要知道它所執行的 Javascript 代碼完全在另一個範圍中,與當前網頁中的代碼不共用範圍。在 Web Worker 中,同樣有一個全域對象(worker 對象本身,this 和 self 引用的都是 worker 對象本身)和其他對象以及方法。Web Worker 中的代碼不能訪問 DOM。那麼 Worker 裡的代碼能訪問哪些對象,擁有哪些方法?

  1. 最小化 的navigator 對象,包括 onLine、appName、appVersion、userAgent 和 platform 屬性
  2. 唯讀 location 對象
  3. setTimeout()、setInterval()、clearTimeout()、clearInterval() 方法
  4. XMLHttpRequest 建構函式

任何時候都能中止 Worker。在 worker.js 中,我們可以用 self.close()方法,而在頁面中,我們可以用 worker.terminal()方法,這時 error 和 message 事件也不會觸發了。

參考文獻:http://mdsa.51cto.com/art/201511/497002.htm

(轉載)WebWorker是什麼鬼?

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在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.