HTML5多線程之--Worker

JavaScript 語言採用的是單線程模型,也就是說,所有任務只能在一個線程上完成,一次只能做一件事。前面的任務沒做完,後面的任務只能等着。隨着電腦計算能力的增強,尤其是多核 CPU 的出現,單線程帶來很大的不便,無法充分發揮計算機的計算能力。

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

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

Web Worker 有以下幾個使用注意點。

(1)同源限制

分配給 Worker 線程運行的腳本文件,必須與主線程的腳本文件同源。

(2)DOM 限制

Worker 線程所在的全局對象,與主線程不一樣,無法讀取主線程所在網頁的 DOM 對象,也無法使用document、window、parent這些對象。但是,Worker 線程可以navigator對象和location對象。

(3)通信聯繫

Worker 線程和主線程不在同一個上下文環境,它們不能直接通信,必須通過消息完成。

(4)腳本限制

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

(5)文件限制

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

基本用法

1.主線程

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

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

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

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

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

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

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

worker.onmessage = function (event) {
  console.log('Received message ' + event.data);
  doSomething();
}

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

主線程可以監聽 Worker 是否發生錯誤。如果發生錯誤,Worker 會觸發主線程的error事件。

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

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

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指定。

self.postMessage()方法用來向主線程發送消息。
self.close()用於在 Worker 內部關閉自身。

以上只是記錄。

http://www.ruanyifeng.com/blog/2018/07/web-worker.html

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