[HTML5] WebWorker Sample Code
在恆逸的上課筆記,上課節奏很快,恕無法詳細說明Orz
WebWorker可以在Javascript實現多執行緒功能,不過有一些限制…
在WebWorker內不能處理畫面DOM元素,只能處理JS資料(複雜計算、Ajax....等等)
目前HTML的畫面處理&渲染,仍然只有一個主執行緒才能處理
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
    <title></title>
</head>
<body>
    <h1>Web worker</h1>
    <div id="result"></div>
    <script>
        var webWorker = new Worker("processScript.js");
        //worker->page
        webWorker.onmessage = function (e) {
            document.getElementById("result").textContent =
                e.data;
        };
        webWorker.onerror = function (e) {
            document.getElementById("result").textContent =
               e.message;
        };
        //page->worker
        webWorker.postMessage("mary");
        document.getElementById("result").textContent =
            "begin...";
    </script>
</body>
</html>
//page->worker
self.onmessage = function (e) {
    //...
    var s = "";
    for (var i = 0; i < 10000 ; i++) {
        s += "abcdefghij";
    }
    //worker->page
    self.postMessage("return:" + e.data);
};
以下是由頁面傳遞JS物件到WebWorker↓
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
    <title></title>
</head>
<body>
   <div id="result"></div>
    <script>
        var webWorker = new Worker("processScript2.js");
        //worker->page
        webWorker.onmessage = function (e) {
            document.getElementById("result").textContent = e.data;
        };
        //error
        webWorker.onerror = function (e) {
            document.getElementById("result").innerHTML = e.message;
        }
        // var msg = {
        //    command: "DOWORK",
        //    name: "mary"
        // };
        var msg = {
            command: "DOMOREWORK",
            name: "mary"
        };
        //page->worker
        webWorker.postMessage(msg);//傳遞JS物件
        document.getElementById("result").textContent = "begin...";
    </script>
</body>
</html>
self.onmessage = function (e) {
    var data = e.data;
    var msg = JSON.stringify(data); //json
    switch (data.command) {
        case "DOWORK": // process the DOWORK command 
            self.postMessage("receive:" + msg); //object->json
            break;
        case "DOMOREWORK": // process the DOMOREWORK command 
            self.postMessage("receive:" + e.data.name); //string(mary)
            break;
        case "FINISH": // tidy up and shut down 
            self.postMessage("Shutting down");
            self.close();
    }
}
將WebWorker要處理的動作改成inline-script寫法↓
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
    <title></title>
    <script id="web-worker" type="javascript/worker">
    //page->worker
self.onmessage = function (e) {
    //...
    var s = "";
    for (var i = 0; i < 20000000; i++) {
        s += "abcdefghij";
    }
    //worker->page
    self.postMessage("return:" + e.data);
};
    </script>
</head>
<body>
    <h1>Web worker</h1>
    <div id="result"></div>
    <script>
        var workerBlob = new Blob([document.querySelector('#web-worker').textContent]);
        var workerURL = URL.createObjectURL(workerBlob);
        var webWorker = new Worker(workerURL);
        // var webWorker = new Worker("processScript.js");
        //worker->page
        webWorker.onmessage = function (e) {
            document.getElementById("result").textContent =
                e.data;
        };
        webWorker.onerror = function (e) {
            document.getElementById("result").textContent =
               e.message;
        };
        //page->worker
        webWorker.postMessage("mary");
        document.getElementById("result").textContent =
            "begin...";
    </script>
</body>
</html>
SharedWorker 同一瀏覽器跨頁籤、跨視窗共用同一個Worker的範例↓
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
    <title></title>
</head>
<body>
    <div id="result"></div>
    <script>
        var sharedWebWorker = new SharedWorker("sharedProcessScript.js");
        sharedWebWorker.port.addEventListener("message", replyHandler, false);
        sharedWebWorker.port.start();
        var data = "mary";
        sharedWebWorker.port.postMessage(data);
        function replyHandler(event) {
            document.getElementById("result").innerHTML = event.data;
        }
    </script>
</body>
</html>
var connections = 0;
var port;
//page->worker
function messageHandler(event) {
    //worker->page
    port.postMessage("hi," + event.data + "," + connections);
}
function connectHandler(event) {
    port = event.ports[0];
    connections++;
    port.addEventListener("message", messageHandler, false);
    port.start();
}
self.addEventListener("connect", connectHandler, false);