昨天介紹了 Shared worker 的基本用法,今天打算寫個範例來了解 Shared worker 的生命週期
目的
Shared worker 及 Shared worker 的生命週期說明
worker 改變 worker 中的 count 變數worker 傳來的 count 變數,由於 count 變數存在於 worker 線程中,因此只要其中一個頁面的改變 count,另一個頁面也能馬上接收到 count 值的改變

首先建立 Shared worker,並分別在按下按鈕後,postMessage +1 或 -1
// 主線程
const worker = new SharedWorker('public/worker.js');
Array.from(document.querySelectorAll('button')).forEach((button) => {
button.addEventListener('click', (e) => {
const { className } = e.target;
switch (className) {
case 'plus':
// 傳遞訊息到 worker (+1)
worker.port.postMessage(1);
break;
case 'minus':
// 傳遞訊息到 worker (-1)
worker.port.postMessage(-1);
break;
default:
break;
}
});
});
在 worker 線程中會定義兩個參數
worker 的所有 port,方便之後統一發送訊息然後當 worker 接收到訊息後,更新 count 的值,並把最新的 count 發送到每個與 worker 有連線的主線程
// worker 線程
let count = 0;
const ports = [];
// 將訊息傳遞到每個與 worker 有連線的主線程
const postMessageToAllPorts = (data) => {
ports.forEach((port) => {
port.postMessage(data);
});
};
onconnect = (e) => {
const port = e.ports[0];
ports.push(port);
postMessageToAllPorts(count);
port.addEventListener("message", (e) => {
// 接收訊息執行 +1 或 -1
count += e.data;
postMessageToAllPorts(count);
});
// 使用 port.addEventListener 寫法時,需要手動 start
port.start();
};
主線程接收到訊息後,將最新的 count 顯示在畫面上
worker.port.onmessage = (e) => {
document.querySelector('.result').textContent = e.data;
};
Shared worker 接收到訊息時,會送出最新的 count 到所有連接的頁面,所以任一頁面改變 count 值後,可以看到其他頁面都會顯示最新的 count 值Shared worker 可以在同源下的不同頁面被呼叫使用,因此只要這些頁面其中一個還開啟著,Shared worker 檔案裡的變數就都還是存在的,因此重整頁面後 count 值的變化會有以下兩種狀況:count 的值會是最新的Shared worker 就會被卸載了,所以重整後的 count 值會回到初始的 0
Shared worker 中執行 console.log() 時,預設無法在 devtool 的 console 面板中看到,這時可以在 Chrome 瀏覽器輸入 chrome://inspect/#workers,接著點擊 inspect 就可以看到 worker 中 log 出來的訊息了