liguofeng29’s blog

個人勉強用ブログだっす。

Worker - javascript内のサブスレッド

Workerはjavascript内でサブスレッドを使用し、サブスレッドとデータのやり取りが行える。 ※サブスレッドではDOM操作はできない。

・サブスレッドで素数を取得するサンプル

<!DOCTYPE html>
<html>

<head>
    <meta http-equiv="Content-Type" content="text/html; charset=SJIS" />
    <title> Worker</title>
</head>

<body>
    <p>素数
        <div id="result"></div>
    </p>
    <script>
        // Worker生成(別スレッドになる)
        var worker = new Worker("worker.js");

        // workerがメッセージ取得時の処理
        worker.onmessage = function(event) {
            document.getElementById("result").innerHTML += event.data + ", ";
        };
    </script>
</body>

</html>

worker.js

var n = 1;
search:
while (n < 99999) {
    // 次の素数
    n += 1;
    for (var i = 2; i <= Math.sqrt(n); i++) {
        if (n % i == 0) {
            continue search;
        }
    }
    // 発見した素数を送信
    postMessage(n);
}

Chromeだとセキュリティエラーがでるね。

・サブスレッドとデータのやり取りを行うサンプル

<!DOCTYPE html>
<html>

<head>
    <meta http-equiv="Content-Type" content="text/html; charset=SJIS" />
    <title> Worker(サブスレッドとデータやり取り) </title>
    <style type="text/css">
        #show {
            width: 400px;
            background-color: #ddd;
            border-collapse: collapse;
        }
        
        td {
            border: 1px solid #555;
        }
    </style>
</head>

<body>
    開始値<input type="text" id="start" name="start" /><br/> 終了値
    <input type="text" id="end" name="end" /><br/>
    <input type="button" value="取得" onclick="getPrime();" />
    <table id="show"></table>
    <script type="text/javascript">
        function getPrime() {
            // 開始値、終了値を取得
            var start = parseInt(document.getElementById("start").value);
            var end = parseInt(document.getElementById("end").value);

            if (start >= end) {
                return;
            }

            // 別スレッド起動してworker.js実行
            var cal = new Worker("worker.js");

            // JSONデータ
            var data = {
                start: start,
                end: end
            };
            // サブスレッドにデータ送信
            cal.postMessage(JSON.stringify(data));
            // データ取得時の処理
            cal.onmessage = function(event) {
                var table = document.getElementById("show");
                table.innerHTML = "";
                // データ取得
                var result = event.data;
                var nums = result.split(",");
                var COLS_NUM = 15;
                for (var i = 0; i <= (nums.length - 1) / COLS_NUM; i++) {
                    var row = table.insertRow(i);
                    for (var j = 0; j < COLS_NUM &&
                        i * COLS_NUM + j < nums.length - 1; j++) {
                        row.insertCell(j).innerHTML = nums[i * COLS_NUM + j]
                    }
                }
            }
        };
    </script>
</body>

</html>

worker.js

// データ取得時
onmessage = function(event)
{
    // JSON変換
    var data = JSON.parse(event.data);
    // 開始値
    var start = data.start;
    // 終了値
    var end = data.end;
    var result = "";
    search:
    for (var n = start ; n <= end ; n++)
    {
        for (var i = 2; i <= Math.sqrt(n); i ++)
        {
            if (n % i == 0)
            {
                continue search;
            }
        }
        // 結果
        result += (n + ",");
    }
    // WorkerオブジェクトのonMessageにデータ送信
    postMessage(result);
}

http://f.st-hatena.com/images/fotolife/l/liguofeng29/20160216/20160216233740.gif?1455633556

・Workerスレッド中に使用できるAPI

  • onmessage
  • postmessage(Data) : Worker.onmessageイベント発生させる
  • importScripts(scripts) : jsの読み込み
  • sessionStorage/localStorage
  • Worker : スレッド内でスレッド生成
  • XMLHttpRequest : 非同期通信
  • navigator
  • location
  • self

※サブスレッド間ではデータのやり取りができず、メインスレッドを通してサブスレッドはデータやり取りを行う。