WebWorker 簡單使用方式


WebWorker 一定程度上可以算得上是瀏覽器中的多線程技術了,在項目中適當使用 Worker 來做一些耗時的操作能大大提高頁面整體流暢度。

Worker的使用也是非常簡單的,通過向 Worker 構造函數傳遞需要在worker中運行的文件路徑作為參數,就可以使得對應的文件運行在worker線程。

Worker線程中沒有 window 對象,也沒有 document 對象。既不能操作也不能創建 DOM。而且 worker 線程和主線程只能通過消息機制來通信。

下面是一個 WebWorker 的簡單用法:

首先需要創建一個 Worker 實例:

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

在 worker.js 中寫下如下代碼:

1 console.log('Hello world');

然后 worker.js 就會在 worker 線程中運行,這也就意味着這里的代碼不管是什么,基本上可以認為對主線程(也就是瀏覽器線程)沒有任何影響。雖然實際上電腦跑的東西越多性能越差,但至少主線程不會被阻塞。

無法跟主線程交互的代碼用處非常有限,當然,你可以繞過去,直接大家都走服務器端結合 WebSocket 來實現跟主線程,但 WebWorker 本身能跟主線程通過消息機制來交互確實會更方便些,如果再允許提交對於 DOM 的操作就更好了。

WebWorker 通過 postMessage 來發送消息,通過 message 事件來接受接收消息。其中發送的數據就在 event.data 中。

比如上面的代碼,由於 worker.js 是通過主線程的代碼加載的,所以執行順序定然晚於主線程的代碼執行,當 worker.js 中的代碼執行后,可以通過向主線程發送一個消息,告訴主線程一切就緒,可以開始開始正常交互了.

這里需要知道的就是 在 worker 中沒有 window 實例,也沒有全局的 this,但是卻有着 WorkerGlobalScope 也就是 self,當前 worker 自己。

1 self.postMessage('ready');

在主線程中通過事件處理程序接收消息

1 worker.addEventListener('message', function (event) {
2     console.log(event.data);
3 });

另外,所有跟 worker 線程交互的代碼也最好在收到 ·ready· 這個消息之后進行。因為此時 worker 線程已經就緒,而且可以在發送 ready 消息之前把必備的准備工作做好。

還有就是消息不要真的就發送簡單的字符串,除非系統里面確實就是這種需求,最好設計下數據結構,采用統一的方式來做消息交互,比如類似下面這樣或者別的方式都行:

{
    cmd: '',
    payload: ...
}

要進行錯誤處理,在主線程和在 worker 中做法很相似,都是添加 “error”事件處理程序,不同的是用 worker 實例還是 WorkerGlobalScope 也就是 self。

1 worker.addEventListener('error', function (event) {
2     console.log('在主線程內監聽 worker 實例的錯誤');
3 });
4 
5 self.addEventListener('error', function (event) {
6     console.log('在 worker 線程內監聽當前 worker 的錯誤');
7 });

類似在 html 文檔中可以使用 <script> 標記導入外部腳本,在 worker 里面也可以導入外部腳本,用法如下:

1 importScripts('script1.js', 'script2', ....);  // 可以導入一個到多個,省略號不是代碼,這行只算是偽代碼

最后用完了 worker 就可以把它關閉了,在主線程中用 terminate,在 worker 線程中直接用用 close 就可以了,用不到時就應該即使關閉,多少能省點系統資源。

1 worker.terminate(); // 在主線程中關閉當前 worker
2 self.close(); // 在 worker 中關閉自己

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM