Javascript - Web Worker 前端多執行緒 - 1

Javascript - Web Worker 研究

.

一般來說, 網頁前端都是單執行緒, 而想要在不影響UI渲染的執行, 充分利用 CPU 的多核計算, 使用 Web Worker.

現行環境下並非所有瀏覽器都有支援, 可以前往查看 各版本瀏覽器的 web worker 支援性

1
2
3
4
    // 可以使用前先判斷當前瀏覽器是否支援
    if (window.Worker) {
      console.log("web worker exists.");
    }

在使用上非常簡單. 直接使用 new Worker 就可以開始使用.

1
    var worker = new Worker('worker.js');

若不想另外弄一隻 worker.js 檔, 可以利用 BlobURL.createObjectURL的方式, 透過把 code 包成參數的方式, 生成網址.

1
2
3
4
5
6
7
    const code = `(function () {
        self.onmessage = function (event){
            // TODO: code...
        }
      })();`;

    var worker = new Worker(URL.createObjectURL(new Blob([code], { type: "text/javascript" })));

補齊 web worker 內的程式碼.

1
2
3
4
5
6
7
8
9
    const code = `(function () {
        self.onmessage = function (event){
          // 接收到資料, 透過 console.log 查看.
          console.log("worker inside get" , event.data);
          
          // 發送出去
          self.postMessage('processd : ' + event.data);
        }
      })();`;

外部接收到 web worker 傳遞出來的訊息的方法也補齊.

1
2
3
    worker.onmessage = function (event) {
        console.log("worker outside get", event.data);
    };

開始把資料發送給 web worker 處理.

1
2
    // 發送給 web worker
    worker.postMessage(123456789);

打開瀏覽器的主控台會看到 console.log 依序印出.

調整應用

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
    const code = `(function () {
        self.onmessage = function (event){
-          // 接收到資料, 透過 console.log 查看.
-          console.log("worker inside get" , event.data);
-       
-          // 發送出去
-          self.postMessage('processd : ' + event.data);
+          let eData = event.data;
+            setInterval(() => {
+              eData = eData * 2;
+              self.postMessage(eData);
+            }, 500);
+          }
      })();`;
      
    worker.onmessage = function (event) {
-      console.log("worker outside get", event.data);
+      document.getElementById("log").innerHTML = "worker response : " + event.data + "<br>" + document.getElementById("log").innerHTML;
    };
    
+    function postMessage() {
+      document.getElementById("log").innerHTML = "post message to worker : " + document.getElementById("data").value + "<br>" + document.getElementById("log").innerHTML;
+      worker.postMessage(document.getElementById("data").value);
+    }

html body 添加以下程式碼.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
<body>
<div>
    <div>
        <label> send worker (repeat number * 2) : </label>
        <input id="data" type="number" value="1" />
        <button onclick="postMessage()">Do</button>
    </div>
    <div id="log"></div>
</div>
</body>

打開瀏覽器, 畫面會長這樣.

點 Do 後會觸發 postMessage() 方法.

再點一次 Do. 並行處理運算計數器.

範例

Web Worker