天天看點

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 線程。

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

繼續閱讀