# 解決JavaScript單線程問題——webWorkers > 參考文檔 [使用 Web Workers - Web API 介面參考 | MDN (mozilla.org)](https://developer.mozilla.org/zh-CN/docs/Web/API/Web_Worker ...
解決JavaScript單線程問題——webWorkers
MDN的介紹為:
Web Worker 為 Web 內容在後臺線程中運行腳本提供了一種簡單的方法。線程可以執行任務而不幹擾用戶界面。此外,它們可以使用
XMLHttpRequest
(儘管responseXML
和channel
屬性總是為空)或fetch
(沒有這些限制)執行 I/O。一旦創建,一個 worker 可以將消息發送到創建它的 JavaScript 代碼,通過將消息發佈到該代碼指定的事件處理器(反之亦然)。
簡單來說就是, 我們可以通過使用worker為主線程分擔數據處理壓力.
假如說你有一段很大的數據需要處理, 而你又不想這段程式阻礙你的其他操作,這時候就可以考慮一下webWorker.
如何使用webWorker
創建worker
-
先創建一個worker.js文件, 該文件為線程代碼文件, 文件中的代碼會在後臺線程中運行.
-
在主線程中創建一個worker, 通過類似通訊的方式在主線程和worker中進行數據傳遞.
// index.js主線程代碼塊 // 簡單創建一個worker名為myworker let myworker = new Worker("./firstworker.js") // 參數為firstworker.js文件的路徑
主線程和worker之間進行通訊
-
主線程發送數據給worker: 在主線程中通過
worker.prototype.postMessage()
進行通信// index.js主線程代碼塊 // ... 創建完worker console.log("主線程我說句話先,接下來你要替我幹活了."); // 簡單向worker中發送一個數組[1, 2, 3] myworker.postMessage([1, 2, 3]);
-
worker接收來自主線程的數據: 在myworker.js中接收數據
// firstworker.js代碼塊 // 接收來自主線程的數據,數組[1, 2, 3] onmessage = function recive(msg) { // 接收到的是一個MessageEvent對象, 我們可以獲取data屬性 console.log(msg.data); // 輸出[1, 2, 3] };
我們也可以使用更簡潔的方式
// firstworker.js代碼塊 // 使用解構和匿名箭頭函數 onmessage = ({ data }) => { console.log(data); // 輸出[1, 2, 3] };
-
worker發送數據給主線程: 通過
postMessage()
發送數據給主線程index.js
接收到數組[1, 2, 3]之後, 我們可以簡單的對數組進行一個逆序操作, 再把結果返回主線程
// firstworker.js代碼塊 onmessage = ({ data }) => { // 主線程發來的數據 console.log("主線程發來的數據:", data); // 賦值一個新變數newdata let newdata = data; // 對新變數操作(數組逆序) newdata.sort((a, b) => { return b - a; }); console.log("worker後臺線程處理完成的數據newdata:", newdata); // 處理完的結果遞交給主線程 postMessage(newdata); };
-
主線程接收worker訊息: 通過
addEventListener()
對worker的動作進行監聽// index.js主線程代碼塊 // 主線程通過 監聽 實例的message事件獲取worker的數據 // 接收myworker處理之後的結果 myworker.addEventListener("message", ({ data }) => { console.log("接收到來自worker處理完的數據:", data); });
關閉線程
worker.terminate()
可以幫助我們在主線程中隨意關閉線程, 即為從主線程中立刻終止一個運行中的 worker
// index.js主線程代碼塊
// 3s後關閉線程
setTimeout(() => {
console.log("關閉myworker,你別說話了")
myWorker.terminate();
}, 3000);
// firstworker.js代碼塊
setTimeout(() => {
console.log("4秒時讓我說句話")
}, 4000);
worker監聽
主線程通過 addEventListener()
對worker動作進行監聽, 動作包含三種
- message
- error
- messageError:
註意事項
- worker是HTML5規範的API,所以你沒法在node環境中使用.
- worker沒辦法對dom元素操作, 只能在主線程中, 多線程操作dom感覺就不大好.
- worker可以用於執行長時間運行的計算、處理大量數據、執行網路請求等任務,而不會影響用戶界面的響應性能.幫助開發人員提高Web應用程式的性能和響應性能.
- 本文章只對worker的使用進行了簡單介紹, 具體進階用法等詳細內容還得參考MDN文檔(共用worker, 線程安全, 嵌入式worker等)