1. 程式人生 > >web worker入門筆記

web worker入門筆記

web worker

Web Worker 的作用,就是為 JavaScript 創造多執行緒環境,允許主執行緒建立 Worker 執行緒,將一些任務分配給後者執行。在主執行緒執行的同時,Worker 執行緒在後臺執行,兩者互不干擾。等到 Worker 執行緒完成計算任務,再把結果返回給主執行緒。這樣的好處是,一些計算密集型或高延遲的任務,被 Worker 執行緒負擔了,主執行緒(通常負責 UI 互動)就會很流暢,不會被阻塞或拖慢。

Worker 執行緒一旦新建成功,就會始終執行,不會被主執行緒上的活動(比如使用者點選按鈕、提交表單)打斷。這樣有利於隨時響應主執行緒的通訊。但是,這也造成了 Worker 比較耗費資源,不應該過度使用,而且一旦使用完畢,就應該關閉。

注意

  • 同源限制

    分配給worker執行緒執行的指令碼檔案,必須與主執行緒的指令碼檔案同源。

  • DOM限制

    worker執行緒無法讀取主執行緒所在網頁的DOM物件,也無法使用window、document物件。可以使用navigator、location物件。

  • 通訊聯絡

    worker執行緒與主執行緒不在同一個上下文環境,他們之間不能直接通訊,必須通過訊息進行通訊。

  • 注意非同步

    worker通訊是使用事件監聽、非同步回撥處理的,所以實際使用中需要注意非同步的問題。

  • 指令碼限制

    worker執行緒不能執行alert()、confirm()方法,但是可以使用XMLHttpRequest傳送ajax請求。

  • 檔案限制

    worker無法讀取本地檔案,他所載入的指令碼必須來自網路。

基本用法

主執行緒
  1. 主執行緒通過 new Worker() 新建一個worker執行緒。
  2. 通過worker.postMessage(data)向worker執行緒傳送資料。data可以是各種型別的資料,也可以是二進位制的資料。
  3. 通過worker.onmessage = callback接受worker發回的資料。
    var worker = new Worker('worker.js');
    worker.postMessage('hello');
    worker.
onmessage = function (e) { console.log(e.data); worker.terminate(); }
worker執行緒
  1. worker執行緒通過this.onmessage = callback接受主執行緒傳來的資料。this指代子執行緒本身,也可以使用self.onmessage,也可以省略onmessage
  2. worker執行緒通過this.postMessage(data)向主執行緒傳送資料。
    this.onmessage = function (e) {
        console.log(e.data);
        this.postMessage('You said: ${e.data}');
    }
worker載入指令碼

在worker內部使用importScripts()載入其他指令碼。

  • importScripts()可以跨域載入js指令碼
  • 通過importScripts()載入的指令碼,就像在html裡面使用script標籤引入的指令碼一樣,指令碼中定義的變數在worker中是全域性的。所以需要注意多個指令碼中不能有同名的變數。
    importScripts('script1.js');
    // 可以跨域載入指令碼
    importScripts('script1.js', 'http://192.168.11.162/script2.js', 'http://192.168.11.162:7070/static/js/script3.js');
錯誤處理

主執行緒使用worker.onerror = callback監聽worker執行緒內部發生的錯誤。

    // 主執行緒
    worker.onerror = function (e) {
        console.log(e);
    }

worker執行緒內部也可以監聽error事件。

    // worker執行緒
    onerror = function (err) {
        console.log(err);
    }
關閉worker

為了節省系統資源,使用完畢建議關閉worker。

主執行緒使用worker.terminate();關閉worker。

worker執行緒使用this.close();關閉worker。