Web workers を使うと、JavaScriptでもマルチスレッドが使えるのですが…
これは使いにくい。
何が使いにくいって、Workerの指定がスクリプトではなくファイルなこと。
そのうえ Same Origin Policy の対象。data: URLも「外様」扱いなのでだめ。
というわけで、こんな workaround を考えてみました。
こんなJSを用意した上で…
http://blog.livedoor.jp/dankogai/js/workaround.jsこうします。
worker = new Worker('http://blog.livedoor.jp/dankogai/js/workaround.js');
worker.msgdom= document.getElementById('result');
worker.onmessage = function(event) {
worker.msgdom.innerHTML = '' + event.data;
};
worker.onerror = function(error) {
console.log(error);
};
var work = function(){
var max = 1e6;
var primes = [2];
var is_prime = function(n){
for (var i = 0; i < primes.length; i++){
var d = primes[i];
if (d * d > n) break;
if (n % d == 0) return 0;
}
primes.push(n);
return n;
};
for (i = 2; i <= max; i++) if(is_prime(i)) postMessage(i);
};
worker.postMessage('' + work);
とりあえず素数を100万まで探索させています。Safariではあっという魔に終わりますが、Firefoxでは結構かかります。途中で飽きたらterminateしてください。setTimeout()なしでもアニメーションできるのは本当に楽ですね。
functionを直接渡さず、文字列として渡しているところがポイントです。それをevalせずにfunction()を取り除いた上でnew Function()しているのは、こうしないと動かないから。変なの。
この回避策、FirefoxとSafariではうまく行くのですが、Chromeでは
となります。つれないですね。
Enjoy!
Dan the Blog Worker
追記:Chromeでも今見たら動きますね。localでやると駄目なだけ?
追^2記:Mobile SafariにはWorkerオブジェクト自体ありませんね。ま、当然か。
このブログにコメントするにはログインが必要です。
さんログアウト
この記事には許可ユーザしかコメントができません。