JavaScript之Web Worker
Web Worker為Web內容在後臺執行緒中執行指令碼提供了一種簡單的方法。執行緒可以執行任務而不干擾使用者介面。此外,他們可以使用XMLHttpRequest執行 I/O(儘管responseXML和channel屬性總是為空)。一旦建立, 一個worker 可以將訊息傳送到建立它的JavaScript程式碼, 通過將訊息釋出到該程式碼指定的事件處理程式(反之亦然)。
Web Worker使用要點
-
同源限制:分配給 Worker 執行緒執行的指令碼檔案,必須與主執行緒的指令碼檔案同源。
-
DOM 限制:Worker 執行緒所在的全域性物件,與主執行緒不一樣,無法讀取主執行緒所在網頁的 DOM 物件,也無法使用document、window、parent這些物件。但是,Worker 執行緒可以navigator物件和location物件。
-
通訊聯絡:Worker 執行緒和主執行緒不在同一個上下文環境,它們不能直接通訊,必須通過訊息完成。
-
指令碼限制:Worker 執行緒不能執行alert()方法和confirm()方法,但可以使用 XMLHttpRequest 物件發出 AJAX 請求。
-
檔案限制:Worker 執行緒無法讀取本地檔案,即不能開啟本機的檔案系統(file://),它所載入的指令碼,必須來自網路。後面我們允許會做處理。
安裝http-server
Worker 執行緒無法讀取本地檔案,即不能開啟本機的檔案系統(file://),它所載入的指令碼,必須來自網路。所以我們得起一個專案。使用http-server
最簡單
安裝:
> cnpm i -g http-server
使用:
> http-server
基本使用
我們新建一個資料夾名叫worker
,裡面新建三個檔案分別是
index.html main.js worker.js
新建一個worker
執行緒很簡單,只需:
var worker = new Worker('worker.js')
main.js
:
var worker = new Worker('./worker.js') console.log('worker running') worker.addEventListener('message',e => { console.log('main: ', e.data); }) // 也可使用: // worker.onmessage = (e)=>{ //console.log('main: ', e.data); // } worker.postMessage('hello worker,I am from main.js')
worker.js
:
console.log('worker task running') onmessage = (e)=>{ console.log('worker task receive', e.data); // 傳送資料事件 postMessage('Hello, I am from Worker.js'); }
在worker資料夾下,命令列輸入http-server,啟動專案,用瀏覽器開啟,看控制檯:
worker running worker task running worker task receive hello worker,I am from main.js main:Hello, I am from Worker.js
從上面可以看到,worker
通過onmessage
來監聽資料,通過postMessgae
來發送資料
終止 worker
worker.terminate();
處理錯誤
worker.addEventListener('error',(e) => { console.log('main error', 'filename:' + e.filename + 'message:' + e.message + 'lineno:' + e.lineno; });
- event.filename: 導致錯誤的 Worker 指令碼的名稱;
- event.message: 錯誤的資訊;
- event.lineno: 出現錯誤的行號;
載入外部指令碼
main.js
var worker = new Worker('./worker1.js');
worker1.js
console.log("I'm worker1") importScripts('worker2.js', 'worker3.js'); // 或者 // importScripts('worker2.js'); // importScripts('worker3.js');
worker2.js
console.log("I'm worker2")
worker3.js
console.log("I'm worker3")