JavaScript - Worker API:釋放並行處理能力

你好,未來的 JavaScript 巫師們!今天,我們將踏上一段令人興奮的旅程,進入 Web Workers 的世界。想像你是一位忙碌廚房中的廚師。有時候,你需要多一双手來帮助你準備一份複雜的菜餚。這正是 Web Workers 對你的 JavaScript 代碼所做的——他們伸出援手,處理繁重任務,而不會減慢你的主廚...我是說,編碼過程!

JavaScript - Worker API

Web Worker API:你的 JavaScript 二厨

Web Worker API 就像在你的 JavaScript 廚房裡有一位助手廚師。它允許你在背景運行腚本,獨立於其他腚本。這意味著你可以執行耗時任務,而不會干擾主頁的性能。酷炫吧?

讓我們深入了解一下我們如何讓這些助手投入工作!

檢查 Web Worker 支援

在我們開始使用 Web Workers 之前,我們需要確保我們的瀏覽器支持它們。這就像在開始烹飪之前檢查你的廚房是否有正確的設備。以下是如何操作:

if (typeof(Worker) !== "undefined") {
// 太好了!Web Workers 受支持
console.log("讓我們開始工作!");
} else {
// 哎呀!Web Workers 不受支持
console.log("對不起,你的瀏覽器不支持 Web Workers");
}

在這段代碼中,我們正在檢查 Worker 對象是否已定義。如果是,我們就可以開始了。如果不是,我們需要找到其他方法來處理我們的任務。

創建 Web Worker 檔案

既然我們知道我們的瀏覽器可以處理 Web Workers,讓我們創建一個!Web Worker 就像我們助手廚師(瀏覽器)將要遵循的配方。我們將為我們的 Web Worker 創建一個獨立的 JavaScript 檔案。

讓我們創建一個名為 worker.js 的文件:

// worker.js
self.addEventListener('message', function(e) {
const result = e.data * 2;
self.postMessage(result);
}, false);

這個 worker 聆聽消息,將收到的數字翻倍,然後將結果發送回去。簡單吧?

創建 Web Worker 對象

現在我們有了我們的 worker 檔案,讓我們在主腚本中創建一個 Web Worker 對象:

let myWorker;

if (typeof(Worker) !== "undefined") {
myWorker = new Worker("worker.js");
} else {
console.log("Web Workers 在你的瀏覽器中不受支持!");
}

這段代碼創建了一個新的 Web Worker 對象,指向我們的 worker.js 檔案。這就像僱用我們的助手廚師並給他們我們的配方。

與 Web Worker 通信

現在,讓我們看看我們如何將任務發送到我們的 worker 並獲得結果:

// 發送數據給 worker
myWorker.postMessage(10);

// 從 worker 接收數據
myWorker.onmessage = function(e) {
console.log("Worker 發回: " + e.data);
};

在這個例子中,我們將數字 10 發送到我們的 worker。Worker 將其翻倍並發送回 20。這就像讓你的助手將配方的食材翻倍一樣!

終止 Web Worker 的執行

當我們完成我們的 Web Worker 時,我們應該結束它以釋放資源。這就像告訴你的助手廚師他們在準備完菜餚後可以回家:

myWorker.terminate();
myWorker = undefined;

這段代碼終止了 worker,並將 myWorker 變量設置為 undefined,有效地刪除了我們對它的引用。

範例:完整的 Web Worker 程序

讓我們把所有東西放在一起,形成一個完整的例子:

<!DOCTYPE html>
<html>
<body>

<p>計數: <output id="result"></output></p>
<button onclick="startWorker()">啟動 Worker</button>
<button onclick="stopWorker()">停止 Worker</button>

<script>
let w;

function startWorker() {
if (typeof(Worker) !== "undefined") {
if (typeof(w) == "undefined") {
w = new Worker("worker.js");
}
w.onmessage = function(event) {
document.getElementById("result").innerHTML = event.data;
};
} else {
document.getElementById("result").innerHTML = "對不起!不支持 Web Worker";
}
}

function stopWorker() {
w.terminate();
w = undefined;
}
</script>

</body>
</html>

這裡是我們的 worker.js

let i = 0;

function timedCount() {
i = i + 1;
postMessage(i);
setTimeout("timedCount()",500);
}

timedCount();

這個例子創建了一個計數的 worker,每半秒更新一次。主頁可以啟動和停止這個 worker,展示了我們如何從主"廚房"控制我們的"助手廚師"。

Web Worker 的使用案例

Web Workers 非常適合那些可能需要很長時間才能完成的任務。以下是一些常見的使用案例:

  1. 複雜計算
  2. 大數據處理
  3. 圖像或視頻處理
  4. 網絡操作
  5. 解析大型數據集(如 CSV 檔案)

將這些視為你的助手廚師可以在不干擾你主要烹飪過程的情況下处理的複雜配方!

Web Workers 和 DOM

有一件事要記住:Web Workers 不能直接訪問 DOM(文件對象模型)。這就像你的助手廚師不能直接為顧客服務菜肴——他們需要先將準備好的食物交給你。

如果 Worker 需要与網頁交云,它必須發送消息給主腚本,然後主腚本可以更新 DOM。

結論

Web Workers 是你 JavaScript 工具箱中的強大工具。它們讓你能够在不減慢主腚本的速度下执行複雜任務,就像一位助手廚師能夠幫助你更有效率地準備複雜菜餚一樣。

記住,有效地使用 Web Workers 的關鍵是識別那些可以獨立於主腚本運行的任務。隨著實踐,你將能夠指揮一個由 Web Workers 組成的廚房,創建出快速、反應靈敏的網頁應用程序,輕鬆處理複雜任務。

祝你好運,願你的 JavaScript 廚房總是熙熙攘攘,高效運行的 Web Workers 不斷!

方法 描述
Worker() 創建一個新的 Web Worker 對象
postMessage() 發送消息給 worker
onmessage 接收 worker 消息的事件處理器
terminate() 終止 worker
addEventListener() 為 worker 添加事件監聽器
removeEventListener() 從 worker 移除事件監聽器

Credits: Image by storyset