Livingdeadの日記: IEのsetTimeoutには発行数に上限がある? 5
JavaScriptのsetTimeout関数についてブラウザごとに挙動が違うようなので調べていた。そのうち、どうやらIEのsetTimeoutには発行数に上限があるのではないかと思えてきた。下のコード、hoge.htmlとでもして保存して開くと、0から30000までの数字が次々と表示される。Firefoxで動かすときにはinnerTextをtextContentに変更する必要がある。
Internet Explorer 8 → 9873 あたりまでしか表示されない。そこそこ速い。
Firefox → 30000まで表示される。そこそこ速い。
Opeara 10 → 30000まで表示される。速い。
Chrome → 30000まで表示されるけどもう後半は実用(?)にならないほど遅い。
なんで?とりあえずJavaScriptの実行エンジンはシングルスレッドであると仮定する。setTimeoutは指定した時間だけたった後で実行キューに投入せよという指令。実行キューはFIFOだとする。キュー長に上限はあるかもしれない。でも f(i, i)のところをf(i,0)としてもf(i,30000)としても変わらないんだよなぁ。キューから取り出されるのはforループが終わってからか。JavaScriptに詳しい人の意見を聞かせてください。
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<title>setTimeout</title>
</head>
<body>
<div>
<p style="text-align:left;">
</p>
</div>
<script type="text/javascript">
function add(x){
e = document.getElementsByTagName("p");
e[0].innerText = e[0].innerText + (" " + x);
}
for (var i = 100; i <= 500; i += 100) {
//delay(i,i);
}
var f = function(x, y){
setTimeout(function(){
add(x);
}, y);
}
for (var i = 1; i < 30000; ++i) {
f(i, i);
}
</script>
</body>
</html>
【追記】2chで訊いてみよう。なんかJavaScriptでゲーム作ってる人とかいたし。
http://pc11.2ch.net/test/read.cgi/hp/1259636243/397-
IE8でやってみた (スコア:0)
ちゃんと29999まで行きました。IEのバージョンはいくつですか?
…IE6 on IETesterでも29999まで行くなあ。純正のIE6だと違うんだろうか。
うちもIE8なんです (スコア:1)
Windows Vista Business SP1
Internet Explorer 8.0.6001.18865
という環境なんですが・・・
そうですか、そちらのIE8では29999まで行きましたか。
うちの環境だと9800台の後半で止まるんですよ。
たとえばボタン作ってonclickのハンドラ作って
1クリックする毎に5000回ループするなんてやれば
いくらでもいけるんですけどね。
うむむ、ますます混乱してきたぞ?
ちょっと他の環境でも試してみます。
屍体メモ [windy.cx]
IE7でも (スコア:0)
IE7で29999まで表示されました (スコア:1)
つまりVista BusinessなノーパソのIE8だけが腐ってるということか。
Windows XP Professional SP3 + IE7.0.5730.13ISでは29999まで表示されました。
ハズレ環境があるということで納得します(ォィ
屍体メモ [windy.cx]
並列処理なら こんな感じでは? (スコア:0)
<html>
<head>
<title>setTimeout</title>
</head>
<body>
<div >
<span id="i"></span>
-
<span id="cnt"></span>
=
<span id="i-sub"></span>
</div>
<div>
<p style="text-align:left;">
</p>
</div>
<script type="text/javascript">
(function(){
var attr = ("innerText" in document.documentElement) ? "innerText" :"textContent";
var cnt=0;
var i = 0;
function add(x){
var e = document.getElementsByTagName("p")[0];
e[attr] = e[attr] + (" " + x);
e = document.getElementById("cnt");
e[attr] = ++cnt;
e = document.getElementById("i-sub");
e[attr] = i-cnt;
}
for (var i = 100; i <= 500; i += 100) {
//delay(i,i);
}
var f = function(x, y){
setTimeout(function(){ add(x); }, y);
};
//for (var i = 1; i < 30000; ++i) {
// f(i, i);
//}
(function(max){
i=0;
var e = document.getElementById("i");
var id=window.setInterval(function(){
e[attr] = i;
f(i, i);
if(++i>max){
window.clearInterval(id);
}
}, 1);
})(30000);
})();
</script>
</body>
</html>