我們知道在 HTML
使用 Javascript
大致上有兩種方式
<head>
或 <body>
中,可以插入帶有 src
的 <script>
標籤,表示從另一個檔案來源中載入執行 js
<html>
<head>
<script src="javascript.js"></script>
</head>
</html>
<script>
標籤中撰寫 js
,這樣在載入 HTML
時 js
會被解析後直接執行<html>
<head>
<script>
alert("Hello World!");
</script>
</head>
</html>
那麽在使用 Web worker
的時候,是否有一個方式可以像以上第二種使用 inline script
的方式,直接將 Web worker
的程式碼寫在 HTML
檔案裡呢?
這種方式就是今天要介紹的 Embedded worker
Step 1. 在 script 標籤中塞入無效的 MIME
通常在 HTML
檔案中使用 Embedded worker
的方式,會在 <script>
標籤中塞入一個無效的 MIME 類型,例如:text/js-worker
,因為是無效的 MIME
所以瀏覽器並不會把之中的程式碼解析當作 javascript
執行
<script type="text/js-worker">
// 撰寫 worker 線程的程式碼
onmessage = (event) => {
const { data } = event;
console.log('worker 接收到的訊息:', event.data);
postMessage('這是 worker 傳出去的訊息');
};
</script>
Step 2. 將 script 標籤中的程式轉換為 blob
為了能夠讓 script
中的程式之後能被 new Worker()
載入使用,需要先轉換為 blob 格式
// 另一個可以正常執行 js 的 script 標籤
<script>
// 將 text/js-worker 類型的 scripts 抓出,並轉換為 blob
const blob = new Blob(
Array.from(
document.querySelectorAll("script[type='text\/js-worker']"),
(script) => script.textContent,
),
{ type: "text/javascript" },
);
</script>
Step 3. 創建 Web worker
最後就可以使用 window.URL.createObjectURL 將 blob
轉為 url
,並丟入到 new Worker()
裡創建 Web worker
const worker = new Worker(window.URL.createObjectURL(blob));
worker.postMessage('傳給 worker 的訊息');
通常當 worker
中的程式碼不多時才會考慮使用 Embedded worker
,因為當牽涉複雜的邏輯時,為了維護性就會傾向把程式碼分拆到各個檔案裡撰寫,或甚至使用 module worker 的方式使共用程式碼更為方便
而我剛好需要用到 Embedder worker
的場景時是在寫 第六天的文章 - postMessage 速度測試 時,那天寫的 範例 不知道為什麼無法在 codesanbox
執行,推測是 codesanbox
的 bug
造成,而在時間緊迫的狀況下我臨時找了另一個線上編輯器 codepen
,但問題是 codepen
是設計來寫一些簡單的 demo
呈現,沒有完整的資料夾結構,只能寫出單一的 .html, .css, .js 檔案,這時剛好 Embedder worker
就派上用場了,可以在單一的 html
檔案中用 Embedder worker
的方式創建出 Web worker
Embedded worker
通常使用在簡單 demo 性質的場景,在單一 HTML
檔案裡就可以直接創建 worker
線程來使用