淺談JavaScript Web Worker線程

1、概述
1.Web Worker 線程是爲JavaScript創造多線程環境,容許主線程建立Worker線程,將一些任務分配給後者執行,(尤爲是一些比較耗時的任務,eg:計算任務)而主線程主要負者用戶UI界面的交互。網絡

2.Worker線程一旦建立成功,就會始終運行,不會被主線程上的活動打斷(好比用戶點擊按鈕,提交表單等)。多線程

2、Web Worker線程的一些特色
1.分配給Worker線程運行的腳本文件,必須與主線程的腳本同源。函數

2.Worker線程沒法使用DOM操做,沒法使用document、window、parent這些對象,可是可使用navigator、location對象post

3.Worker線程和主線程不在同一個上下文環境,它們不一樣直接通訊,必須經過消息完成(postMessage、onmessage)this

4.Worker線程不能執行alert()方法和confirm()方法,可是可使用XMLHttpRequest對象發出AJAX請求線程

5.Worker線程沒法讀取本地文件,既不能打開本機的文件系統(file://),它所加載的腳本,必須來自網絡。code

3、基本用法
1.主線程對象

var worker = new Worker(‘worker.js’);     //建立Worker線程

主線程使用worker.postMessage('...');方法,向Worker發信息事件

worker.postMessage('Hello World');
worker.postMessage({method: 'echo', args: ['Work']});

worker.postMessage()方法的參數,就是主線程傳給 Worker 的數據。它能夠是各類數據類型,包括二進制數據。ip

主線程經過worker.onmessage指定監聽函數接收子線程發回來的消息

worker.onmessage = function (event) {
    //event.data表示主線程傳遞給Worker線程的數據
  console.log('Received message ' + **event.data**);
  doSomething();
}

function doSomething() {
  // 執行任務
  worker.postMessage('Work done!');
}

上面代碼中,事件對象的data屬性能夠獲取 Worker 發來的數據。

Worker 完成任務之後,主線程就能夠把它關掉。

worker.terminate();

2.Worker線程

Worker 線程內部須要有一個監聽函數,監聽message事件。

self.addEventListener('message', function (e) {
  self.postMessage('You said: ' + e.data);
}, false);

上面代碼中,self表明子線程自身,即子線程的全局對象。所以,等同於下面兩種寫法。

// 寫法一
this.addEventListener('message', function (e) {
  this.postMessage('You said: ' + e.data);
}, false);

// 寫法二
addEventListener('message', function (e) {
  postMessage('You said: ' + e.data);
}, false);

除了使用self.addEventListener()指定監聽函數,也可使用self.onmessage指定。監聽函數的參數是一個事件對象,它的data屬性包含主線程發來的數據。self.postMessage()方法用來向主線程發送消息。

根據主線程發來的數據,Worker 線程能夠調用不一樣的方法,下面是一個例子。

self.addEventListener('message', function (e) {
  var data = e.data;
  switch (data.cmd) {
    case 'start':
      self.postMessage('WORKER STARTED: ' + data.msg);
      break;
    case 'stop':
      self.postMessage('WORKER STOPPED: ' + data.msg);
      self.close(); // Terminates the worker.
      break;
    default:
      self.postMessage('Unknown command: ' + data.msg);
  };
}, false)

上面代碼中,self.close()用於在 Worker 內部關閉自身。

3.Worker加載腳本

Worker 內部若是要加載其餘腳本,有一個專門的方法importScripts()

importScripts('script1.js');

該方法能夠同時加載多個腳本

importScripts('script1.js', 'script2.js');

4.錯誤處理

主線程能夠監聽 Worker 是否發生錯誤。若是發生錯誤,Worker 會觸發主線程的error事件

worker.onerror(function (event) {
  console.log([
    'ERROR: Line ', e.lineno, ' in ', e.filename, ': ', e.message
  ].join(''));
});

// 或者
worker.addEventListener('error', function (event) {
  // ...
});

Worker 內部也能夠監聽error事件

5.關閉Worker

使用完畢,爲了節省系統資源,必須關閉 Worker。

// 主線程
worker.terminate();

// Worker 線程
self.close();
相關文章
相關標籤/搜索