このページの本文へ

JavaScriptで並列処理ができる「Web Workers」 (5/5)

2010年10月13日 11時00分更新

文●古籏一浩

  • この記事をはてなブックマークに追加
本文印刷

時間のかかる処理をワーカーに置き換える

 実際に時間がかかる処理をWeb Workersを使って並列処理してみましょう。前回のFile APIを使ったファイル処理のスクリプトを少し変更して、ファイル内に0がいくつあるか調べるプログラムを作ります(Firefox 3.6以降でのみ動作します)。

 ワーカーを使わないプログラムがサンプル4です。サンプル4を実行すると以下の図のようにスクリプトの停止を確認するダイアログが表示され、スクリプトの動作を停止させるまでウィンドウ内のボタン(ホームや戻るボタンなど)が操作できなくなります。

【図13】fig13.png

スクリプトを実行するとUIの操作が全くできなくなり……

【図14】fig14.png

スクリプトを停止するかどうかのダイアログが表示される。「処理を実行」ボタンをクリックして処理を続けると……

【図15】fig15.png

結果が表示される。あまりに時間がかかる場合には何度もスクリプト停止のダイアログが表示される

サンプル4


<!DOCTYPE html>
    <head>
        <meta charset="utf-8" />
        <title>バイナリデータ内に0がいくつあるか調べる</title>
    </head>
    <body>
        <h1>バイナリデータ内に0がいくつあるか調べる</h1>
        <form action="./test.cgi" method="get">
            <input type="file" id="myFile" />
            <input type="button" id="checkStart" value="調査開始" />
        </form>
        <div id="result"></div>
        <script>
            document.getElementById("checkStart").addEventListener("click", function(){
                document.getElementById("result").innerHTML = "調査中...";
                var fileData = document.getElementById("myFile").files[0];  // 最初のファイルだけ
                var reader = new FileReader();
                reader.onload = function(evt){
                    var count = 0;
                    for(var i=0; i<fileData.size; i++){
                        var data = evt.target.result.charCodeAt(i);   // 1バイト読み出し
                        if (data == 0) {
                            count++;    // 読み出したデータが0だったらカウントアップ
                        }
                    }
                    document.getElementById("result").innerHTML = count+"<br />"; // 結果をページ上に表示
                }
                reader.readAsBinaryString(fileData);
            }, true);
        </script>
    </body>
</html>


 このサンプル4をワーカーを使ったプログラムに変更します。

 処理に時間がかかる「reader.onload〜」の部分を抜き出して別ファイルとして保存します。ワーカーではDOM操作ができませんのでDOM操作部分を削除し、代わりにpostMessage()メソッドを使って、呼び出し元に結果をメッセージとして送信します。

 実際のプログラムはサンプル5です。

サンプル5[HTML]


<!DOCTYPE html>
    <head>
        <meta charset="utf-8" />
        <title>Web Workersを使ってバイナリデータ内に0がいくつあるか調べる</title>
    </head>
    <body>
        <h1>Web Workersを使ってバイナリデータ内に0がいくつあるか調べる</h1>
        <form action="./test.cgi" method="get">
            <input type="file" id="myFile" />
            <input type="button" id="checkStart" value="調査開始" />
        </form>
        <div id="result"></div>
        <script>
            document.getElementById("checkStart").addEventListener("click", function(){
                document.getElementById("result").innerHTML = "調査中...";
                var fileData = document.getElementById("myFile").files[0];  // 最初のファイルだけ
                var reader = new FileReader();
                reader.onload = function(evt){
                    // ワーカー設定
                    var myWorker = new Worker("analysis.js");
                    myWorker.addEventListener("message", function(event){
                        document.getElementById("result").innerHTML = event.data+"個ありました。";
                    }, true);
                    myWorker.postMessage({
                        size: fileData.size,
                        contents: evt.target.result
                    });
                }
                reader.readAsBinaryString(fileData);
            }, true);
        </script>
    </body>
</html>


サンプル5[analysis.js]


addEventListener("message", analysis, false);
function analysis(event){
    var count = 0;
    var fSize = event.data.size;    // ファイルサイズ
    var fData = event.data.contents;    // ファイルデータ
    for(var i=0; i<fSize; i++){
        var data = fData.charCodeAt(i);   // 1バイト読み出し
        if (data == 0) {
            count++;    // 読み出したデータが0だったらカウントアップ
        }
    }
    postMessage(count);
}



 次回は、引き続きWeb Workersを使って、画像分析するプログラムを作成します。

前へ 1 2 3 4 5 次へ

この連載の記事

一覧へ

この記事の編集者は以下の記事をオススメしています