[HTML5] WebWorker Sample Code

[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);