昨天介紹了 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 出來的訊息了