2012年10月31日水曜日

jQuery DeferredとSafariとalert


※この記事は問題が発生したが原因が分からなかったため、知ってたら教えて欲しいという記事です。

"jQuery Deferred API"という非同期処理のためのオブジェクトがjQueryにあります。

「Deferredって何?」と思った方は検索欄に「jQuery Deferred」と入れて調べてくださいな。

そのDeferredのサンプルを書いていて気づいたのだが、Safariだけ動かした時だけおかしな挙動になるケースがあった。

それは以下のコード
var doAaa = function() {
    var dfd = $.Deferred();

    setTimeout(function() {
        $('#BList').append('<li>aaa</li>');
        dfd.resolve();
    }, 1000);

    return dfd.promise();
};

var doBbb = function() {
    alert('doBbb done');
};

var doSampleB = function() {
    // clear
    $('#BList').empty();

    doAaa().done(doBbb);
};


Deferredを用いて、doAaaの実行後にdoBbbを実行するというもの。doAaaは画面に"aaa"と表示させて、doBbbは単にalertを表示させている。HTMLではボタンを押すとdoSampleBが実行されるように作った。

なので、"aaa"と表示した後にalertが出るのが正しい、と思っている。

だが、safariだけ"aaa"と表示する前にalertが出てしまう(´・ω・`)

chromeの場合は想定どおり

safariの場合は先にalertが出る

先に出たalertを閉じるとaaaが表示される。

Firefox、IE、Operaでも試したが、こちらは想定どおり(chromeと同じ)だった。
OSをWindowsからMacに変えて試したが、こちらでもsafariだけ先にalertが出た。

ちなみに、"aaa"と表示するところをalertで出した場合は、どのブラウザでも正しい順序でalertが出た。
doBbb内でalert出すところをjQueryで"bbb"と表示するように変えたが、どのブラウザでも正しく"aaa"、"bbb"の順で表示された。

なので、描画とalert周りがブラウザによって何か制御が違うのかなという気がするが、それ以上のことはよく分からず(´・ω・`)
誰か知っている人がいたら教えてください。