Web Worker

概述

我們都知道JavaScript是一門單線程語言,其單線程帶來了很大的不便。Web Worker的出現就是爲JavaScript創造多線程的環境,運行主進程創建Worker線程,將一些任務分配給Worker線程運行。主線程運行的同時,Worker線程在後臺運行,兩者互不干擾。Worker線程計算的結果返回給主線程,這樣主線程在面對計算密集型或高延遲的任務,就會比較流暢。

Web Worker的特點

  • Worker線程一旦創建成功,就會始終運行。即使主線程卡死,它依然在運行。這樣有利於與主線程通信,但是這也造成了Worker比較浪費資源,所以,一旦用完,我們就應該關閉它。
  • 同源限制: 分配給Worker線程運行的腳本文件,必須與主線程的腳本文件同源
  • DOM限制: 不能操作主線程中的DOM,要保持DOM的唯一性。documentwindowparent這些對象都無法使用。可以使用navigatorlacation(只讀)XMLHttpRequestsetTimeout等API。
  • 腳本限制: Worker線程不能執行alert()、confirm()這些方法。但可以使用 XMLHttpRequest 對象發出 AJAX 請求。
  • 文件限制: 不可以讀取本地文件(js主線程也不能)。出於安全性考慮,瀏覽器不允許js讀取本地文件。
  • 兩類線程: Web Worker定義了兩類工作線程:專用線程(只有一個頁面可以使用這個線程)與共享線程(多個同源頁面可以共享一個線程)。

基本使用

主線程
  • 創建Web Worker

    主線程採用new命令,調用Worker()構造函數,創建一個Worker線程:

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

    Worker()構造函數的參數是一個腳本文件,該文件就是Worker線程要執行的任務,

  • 向Web Worker發送消息

    主線程採用worker.postMessage()方法,向Worker發消息。

     worker.postMessage('hello');
     worker.postMessage( {number: 10})
    

    worker.postMessage()中的參數,就是主線程傳給Worker的數據。它可以是任意類型,包括二進制

  • 主進程接受子線程發回的消息

    worker.onmessage = function(event) {
    	console.log('received  worker  message' + event.data);
    }
    
    // 或者
    Worker.addEventListener('message', event => {
          console.log('received worker data', event.data);
    }, false);
    
  • 主進程監聽Worker是否發生錯誤

    如果發生錯誤,Worker 會觸發主線程的error事件。

    worker.onerror(function (event) {
    	 // ...
    })
    // 或者
    worker.addEventListener('error', function (event) {
      // ...
    });
    
  • 主線程關閉線程

    Worker完成任務之後,主進程就可以關閉它。

    worker.terminate();
    
Worker線程
  • 監聽來自主線程的數據

    self.addEventListener('message' ,function(event) {
    		self.postMessage('You said:' event.data);
    	},false);
    // 等同於
    this.addEventListener('message' ,function(event) {
    		this.postMessage('You said:' event.data);
    },false);		
    

    self表示子線程自身,當然也可以使用self.onmessage來監聽。self.postMessage()方法用來向主線程發送消息。

  • Worker自身關閉

    Worker線程可以在內部自己關閉,使用close()方法。

  • Worker加載腳本

    Worker內部如果要加載其他腳本,有一個專門的方法importScripts()

    importScripts('script1.js');
    // 可以同時加載多個腳本
    importScripts('script1.js', 'script2.js');
    

使用場景

  • 數學運算
    Web Worker最簡單的應用就是用來做後臺計算,對CPU密集型的場景再適合不過了。
  • 圖像處理
    通過使用從<canvas>中獲取的數據,可以把圖像分割成幾個不同的區域並且把它們推送給並行的不同Workers來做計算,對圖像進行像素級的處理,再把處理完成的圖像數據返回給主頁面。
  • 大數據的處理
    目前mvvm框架越來越普及,基於數據驅動的開發模式也越愈發流行,未來大數據的處理也可能轉向到前臺,這時,將大數據的處理交給在Web Worker也是上上之策了吧。

常用API總結

主線程中的API:

  • worker.postMessage(): 主線程往worker線程發消息,消息可以是任意類型數據,包括二進制數據
  • worker.terminate(): 主線程關閉worker線程
  • worker.onmessage(): 指定worker線程發消息時的回調,也可以通過worker.addEventListener(‘message’,cb)的方式
  • worker.onerror: 指定worker線程發生錯誤時的回調,也可以worker.addEventListener(‘error’,cb)

Worker線程中的API:

  • self.postMessage: worker線程往主線程發消息,消息可以是任意類型數據,包括二進制數據
  • self.close: worker線程關閉自己
  • self.onmessage: 指定主線程發worker線程消息時的回調,也可以self.addEventListener(‘message’,cb)
  • self.onerror: 指定worker線程發生錯誤時的回調,也可以 self.addEventListener(‘error’,cb)

參考文章:

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章