2008-06-06

FirefoxのsetIntervalに不具合?

FirefoxのsetIntervalは複数を一度に登録して実行するとまとめて処理してしまいます。次のコードは1秒間隔で3回、テキストエリアに実行回数と時間(秒.ミリ秒)を出力する関数を定義して、それを10回呼び出しています。
// 関数を定義
var textarea = document.f.ta;
var fn = function(){
var count = 0;
var id = window.setInterval(function(){
count++;
var d = new Date();
textarea.value += count + " : " + d.getSeconds()
+ "." + d.getMilliseconds() + "\n";
if(count > 2){
clearInterval(id);
}
}, 1000);
};

// 10回呼び出す
for(var i=0; i<10; i++){
fn();
}

これを実行するとFirefox以外は一秒毎に3回10行づつ出力され、合計30行が出力されるます。期待する結果どおりで正しいです。それがFirefoxは一秒後に30行出力されてしまいます。
// Firefox以外
1 : 2.843
1 : 2.859
1 : 2.859
1 : 2.859
1 : 2.859
1 : 2.859
1 : 2.859
1 : 2.859
1 : 2.859
1 : 2.859
2 : 3.859
2 : 3.859
2 : 3.859
2 : 3.859
2 : 3.859
2 : 3.859
2 : 3.859
2 : 3.859
2 : 3.859
2 : 3.859
3 : 4.859
3 : 4.859
3 : 4.859
3 : 4.875
3 : 4.875
3 : 4.875
3 : 4.875
3 : 4.875
3 : 4.875
3 : 4.875

// Firefox
1 : 51.843
1 : 51.859
1 : 51.859
1 : 51.859
1 : 51.859
1 : 51.859
1 : 51.859
1 : 51.859
1 : 51.859
1 : 51.859
2 : 51.859
2 : 51.859
2 : 51.875
2 : 51.875
2 : 51.875
2 : 51.875
2 : 51.875
2 : 51.875
2 : 51.875
2 : 51.890
3 : 51.890
3 : 51.890
3 : 51.890
3 : 51.890
3 : 51.906
3 : 51.906
3 : 51.906
3 : 51.906
3 : 51.921
3 : 51.921

自分のコードが悪いのかと思ったのですが、見直しても悪く思えません。試しにMozilla 1.0とNetscape 7.1で試したところ、Mozillaは他のブラウザと同様の結果となりましたが、NetscapeはFirefoxと近い結果になりました(1回と2回が一秒後に出力。3回目は2秒後に出力)。

setTimeoutを使って同じ処理を実行したところ、こちらは問題ありませんでした。一回毎にsetTimeoutで登録しなおしているからでしょうか。

他にも例では10個同時に実行してますが、一つだけだとFirefoxも期待通りに動きます。またディレイ時間を20msづつずらすとこちらも期待通りに動くようになります。

どうも同じタイミングで動き出すような登録はよくないようです。Firefoxではディレイ時間に気をつけないと…。

それにしてもMozilla 1.0の頃は問題なかったのが最近のはダメってデグレートでは?気になります。でもBugzilla追うのは面倒なのでそっとしておこう。

2 件のコメント:

nakajiman さんのコメント...

同じコードを試してみましたが、エントリのとおり不思議な振る舞いをしますね。for が1回のときは期待どおり、2回以降は setInterval の中身が複数回連続して実行されますね。

似たものだと、これかなぁ。

Bug 234016 – Incorrect fire sequence for multiple synchronized setInterval timers
https://bugzilla.mozilla.org/show_bug.cgi?id=234016

aquilegia さんのコメント...

Bug 234016 まさにこれです。探して頂いき感謝です。Bugzillaに添付されていた確認プログラムを除いたみたところ、同時実行数は3個と少ないですが、事象は起きていました。

2.0.0.7で修正されたのを確認したようなことが書かれていますが本当に直ったのかな。2.0.0.14で起こるのでそうは思えませんが・・・。3.0rc2で試したところ、こちらは直っていました。

またデグレートしないことを願いますw