js Worker 線程


    在平時的運行的javascript腳本都在主線程中執行,如果當前腳本包含復雜的、耗時的代碼。那么JavaScript腳本的執行將會被阻塞,甚至整個劉看齊都是提示失去響應。

例子:

   假設程序需要計算、收集1~9999的之間所有質數,不采用后台線程,而是之間是使用JavaScript前台線程的計算、收集質數。代碼如下。

 

<html>
<head>
    <meta name="author" content="Yeeku.H.Lee(CrazyIt.org)" />
    <meta http-equiv="Content-Type" content="text/html; charset=GBK" />
    <title> 計算質數 </title>
</head>
<body>
    <p>已經發現的所有質數:<div id="result"></div></p>
    <script type="text/javascript">
        var n = 1;
        search: 
        while (n < 99999) 
        {
            // 開始搜尋下一個質數
            n += 1;
            for (var i = 2; i <= Math.sqrt(n); i++)
            {
                // 如果除以n的余數為0,開始判斷下一個數字。
                if (n % i == 0)
                {
                    continue search;
                }
            }
            document.getElementById('result').innerHTML += (n + ", ");
        }
    </script>
</body>
</html>

 

瀏覽器久久未響應,一篇空白。最后過來七八秒全部崩出來。如果改為使用webWorker啟用多線程呢?使用Worker創建賢臣非常簡單,只要調用Worker的構造器就可以。

        Worker(scriptURL):scriptURL用於指定所使用JavaScript腳本的路徑

<html xmlns="http://www.w3.org/1999/xhtml">
<head>
    <title></title>
    <script>
        var worker = new Worker('worker12.js');
        worker.onmessage = function (event) {
            document.getElementById("result").innerHTML += event.data + ",";
        }
         
    </script>
</head>
<body>
    <p>
        已經發現的所有質數:<div id="result" style="width: 1500px; height:auto; border:1px solid red; word-wrap: break-word; ">
        </div>
    </p>
</body>
</html>

Worker.js

var n = 1;
search:
while (n < 10000) {
    // 開始搜尋下一個質數
    n += 1;
    for (var i = 2; i <= Math.sqrt(n); i++) {
        // 如果除以n的余數為0,開始判斷下一個數字。
        if (n % i == 0) {
            continue search;
        }
    }
    // 發現質數
    postMessage(n);
}

 

 注意:

   Worker啟動的子線程找到質數之后,並不能之間把找到的質數更新在頁面上顯示,必須通過postMessage(n)發送消息給前台JavaScript通信。

 

 

 

 

 例子2:Worker線程交換數據:

<html xmlns="http://www.w3.org/1999/xhtml">
<head>
    <title>多個線程交換數據</title>
    <script>
        var car = function () {
            var start = document.getElementById("start1").value;
            var end = document.getElementById("end1").value;

            if (start >= end) {
                return;

            } else {

                var cal = new Worker("Worker.js");
                // 定義需要提交給Worker線程的數據
                var data = {
                    start: start,
                    end: end
                };
                // 向Worker線程提交數據。
                cal.postMessage(JSON.stringify(data));
                cal.onmessage = function (event) {
                    document.getElementById("result").innerHTML += event.data + ",";
                }
            }
        }
           
    </script>
</head>
<body>
    起始值:<input type="text" id="start1" /><br />
    結束值:<input type="text" id="end1" /><br />
    <input type="button" value="點擊" onclick="car();" />
    <div id="result" style="width: 1500px; height: auto; border: 1px solid red; word-wrap: break-word;">
    </div>
</body>
</html>

worker.js

 
onmessage = function (event) {
    // 將數據提取出來。
    var data = JSON.parse(event.data);
    // 取出start參數
    var start = data.start;
    // 取出end參數
    var end = data.end;
    var result = "";
    search:
    for (var n = start; n <= end; n++) {
        for (var i = 2; i <= Math.sqrt(n); i++) {
            // 如果除以n的余數為0,開始判斷下一個數字。
            if (n % i == 0) {
                continue search;
            }
        }
        // 搜集找到的質數
        result += (n + ",");
    }
    // 發送消息,將會觸發前台JavaScript腳本中
    // Worker對象的onmessage方法
    postMessage(result);
}

 

例子3:多個線程嵌套

 

<html xmlns="http://www.w3.org/1999/xhtml">
<head>
    <title>多個線程嵌套 </title>
    <script>
        var car = function () {
            var start = document.getElementById("start1").value;
            var end = document.getElementById("end1").value;
            var count = document.getElementById("count1").value;

            var worker = new Worker('worker.js');
            var data = {
                start: start,
                end: end,
                count: count
            };
            worker.postMessage(JSON.stringify(data));
            worker.onmessage = function (event) {
                document.getElementById("result").innerHTML += event.data + ",";
            }

        }
     
 
    </script>
</head>
<body>
    起始值:<input type="text" id="start1" /><br />
    結束值:<input type="text" id="end1" /><br />
    個數:<input type="text" id="count1" /><br />
    <input type="button" value="點擊" onclick="car();" />
    <div id="result" style="width: 1500px; height: auto; border: 1px solid red; word-wrap: break-word;">
    </div>
</body>
</html>

worker.js

onmessage = function (event) {
    // 將數據提取出來。
    var data = JSON.parse(event.data);
    // 取出start參數
    var start = data.start;
    // 取出end參數
    var end = data.end;
    // 取出count參數
    var count = data.count;
    var result = "";
    search:
    for (var n = start; n <= end; n++) {
        for (var i = 2; i <= Math.sqrt(n); i++) {
            // 如果除以n的余數為0,開始判斷下一個數字。
            if (n % i == 0) {
                continue search;
            }
        }
        // 搜集找到的質數
        result += (n + ",");
    }
    // 再次啟動Worker線程
    var sub = new Worker("subworker.js");
    // 把需要處理的數據傳入啟動的Worker線程中
    sub.postMessage({ result: result, count: count });
    sub.onmessage = function (event) {
        // 發送消息,將會觸發前台JavaScript腳本中
        // Worker對象的onmessage方法
        postMessage(event.data);
    }
     
}

subworker.js

onmessage = function (event) {
    // 將數據提取出來。
    var data = event.data;
    // 提取所有質數
    var primeNums = data.result.split(",")
    var randResult = "";
    for (var i = 0; i < data.count; i++) {
        // 計算一個隨機索引值
        var randIndex = Math.floor(Math.random()
            * (primeNums.length - 1));
        // 隨機地"收集"一個質數
        randResult += (primeNums[randIndex] + ",");
    }
    // 發送消息,將會觸發啟動它的JavaScript腳本中
    // 對應Worker對象的onmessage方法
    postMessage(randResult);

}

 

 

 

 

 

 

 

  


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM