totorajの開発日記

僕がなんかメモる

Web Workersをファイル分けせずに使う

タイトル通りです。

方法

Workerとして実行するスクリプトをBlobを使ってファイルにします。

生成されたファイルのURLを取得してWorkerにするだけです!

ソースコード

createWorkerがWorkerを作るメソッドです。

参考:

// Workerを生成
var worker = createWorker(workerScript);
console.time("prime");
// Workerにメッセージを投げる
worker.postMessage(1000000);
// Workerからメッセージを受け取る
worker.addEventListener("message", function (event) {
    console.timeEnd("prime");
    document.querySelector("body").innerHTML = event.data.join(", ");
});

/**
 * 渡されたFunctionからWorkerを作って返す
 * @param {Function} script - Workerにするスクリプト
 * @return {Worker}
 */
function createWorker(script) {
    // 正規表現を使ってメソッド内のスクリプトのみを抽出
    var re = /^function\s*\w*\s*\([\w\s,]*\)\s*{([\w\W]*?)}$/,
        body = script.toString().trim().match(re)[1];
    // Blobを使いファイルを生成
    var blob = new Blob([body], {type: "text/javascript"});
    // BlobのURLを取得
    var url = URL.createObjectURL(blob);
    
    // Workerを作って返す
    return new Worker(url);
}

/**
 * Workerとして動かすスクリプト
 */
function workerScript() {
    
    addEventListener("message", function (event) {
        postMessage(prime(event.data));
    });
    
    function prime(limit) {
        var primes = [];
        if (limit < 2) return primes;
        primes.push(2);
        if (limit <= 2) return primes;
        for (var i=3; i <= limit; i++) {
            for (var j=0; j < primes.length; j++) {
                if (i % primes[j] === 0) break;
                if (j+1 >= primes.length) primes.push(i);
            }
        }
        return primes;
    }
}

Web Workersを利用した素数一覧表示テスト - Gist

おわりに

めっちゃ薄っぺらいないようですね・・・。

久々の更新だから仕方ない!