Hatena::Groupmoz-addon

Ci.nsIZIGOROu

2008-10-09

setTimeout + document.cookie

| 00:54 |  setTimeout + document.cookie  - Ci.nsIZIGOROu を含むブックマーク はてなブックマーク -  setTimeout + document.cookie  - Ci.nsIZIGOROu

こういうスクリプトを走らせた時の挙動メモ。但し単独じゃなくてこのページをほぼ同時期に複数タブで実行した場合。

<!DOCTYPE HTML>
<html>
  <head>
    <title>cookie + setTimeout test</title>
    <script type="text/javascript">
      //<![CDATA[
var c_incr = function() {
  var c = document.cookie; 
  document.cookie = "c=" + (parseInt ( c.substring(c.indexOf("c=") + 2) || 0 ) + 1 );
};

window.onload = function() {
  setTimeout(function() {
    var limit = 10000;
    
    for (var i = 0; i < limit; i++) {
      setTimeout(c_incr, 0);
    }

    setTimeout(function() { alert(document.cookie); }, 0);
  }, 1000 * 3);
};
      //]]>
    </script>
  </head>
  <body>
    <h1>cookie + setTimeout test</h1>
  </body>
</html>

で、期待する結果は当然 c の値に limit の数値 10,000 が出る事な訳です。

さらにこのHTML置いた所を複数のタブで開いて、なるべく同じタイミング、少なくとも直前のスクリプトが終わる前に実行すると。

その場合、後から開いたタブの方で期待する所では 20,000 とか出て欲しい訳です。ちなみにやり直す場合は document.cookie の値を初期化する必要ありです。

結果

OSWinXP です。

browser c
IE7 15981
Fx3 20000
Opera 9.5 19995
Safari 4 20000
Chrome 0.2 16065

まぁこの結果見ると 20,000 と言う結果が出るブラウザの方がひょっとしたらたまたまで、他のブラウザの結果が普通かもしれない。まぁその是非は置いといて少なくとも言える事は、20,000にならないブラウザは、setTimeout() に指定した関数内の処理も非同期になっていて、実行順序が保障されてないと考えられる。

もう少し分かりやすく言うと、

と言う実行順序ならば問題なく、この場合20,000になるんだけども、20,000 にならないブラウザはこの順序どおりには実行されないと言う事だと考えられる。

まぁ逆に 20,000 になるブラウザは無いと思ってたので Fx3, Safari4の実行結果の方にびっくりした。

メモ

これは実は 20,000 となるならば複数のウインドウ存在していた場合、document.cookie を通じて、シーケンス値を発番出来るかなと期待してたんだけど、案の定出来なかったという結論。