jQuery.ajax()の非同期通信で実行順序を保証する方法を紹介します。
具体的には、jQuery.ajax()による非同期通信を連続して実行する場合やjQuery.ajax()メソッドによる非同期通信と他の処理を続けて実行する場合、お互いの実行順序を保証する方法です。
本エントリーではjQuery1.8を使って解説します。その関係で、done()メソッドを使っています。done()がサポートされていないバージョンであればsuccess()に読み替えてください。
「仕様」という表現は適切でないかもしれませんが、例えばjQuery.ajax()による非同期通信を連続実行した場合、実行結果の順序は不定です。
簡単なサンプルとして、for文の中でjQuery.ajax()を実行するコードを用意しました。
<meta charset="utf-8" /><script src="http://ajax.googleapis.com/ajax/libs/jquery/1.8/jquery.min.js"></script><script>var list = new Array('test1.html', 'test2.html', 'test3.html');for (i=0; i<3; i++) { var url = list.shift();$.ajax({ url: url, }).done(function(html) {console.log(html); });}</script>test1.html~test3.htmlには、それぞれ「test1」「test2」「test3」という文字列が設定されています。
このコードを実行すると、成功時に起動されるdone()メソッド内に記述したconsole.log()の出力は、期待した順序(test1→test2→test3)になりません。
Firebugで確認したところ、console.log()の出力結果は次のようになるケースがありました。

上のサンプルはjQuery.ajax()同士の実行順序ですが、jQuery.ajax()と他の処理についても同様です。
次のサンプルでは、一番下のconsole.log()が先に実行される場合があります。というか、ほぼ先に実行されます。
<meta charset="utf-8" /><script src="http://ajax.googleapis.com/ajax/libs/jquery/1.8/jquery.min.js"></script><script>$.ajax({ url: 'test1.html',}).done(function(html) {console.log(html);});console.log("foo");</script>2項および3項に非同期通信で実行順序を保証する方法を示します。
1項のサンプルで、実行結果をtest1.html、test2.html、test3.htmlの順で保証したい場合、done()メソッドまたはalways()メソッドから再帰的にjQuery.ajax()を呼び出すようにすればOKです。
<meta charset="utf-8" /><script src="http://ajax.googleapis.com/ajax/libs/jquery/1.8/jquery.min.js"></script><script>var list = new Array('test1.html', 'test2.html', 'test3.html');var foo = function(){ var url = list.shift();$.ajax({ url: url }).done(function(html) {console.log(html); if (list.length) {foo(); } });};foo();</script>もっとエレガントな実装があると思いますが、ここではjQuery.ajax()を関数fooでラップし、done()メソッドから関数fooを再帰呼び出しするようにしています。
Firebugで確認したconsole.log()の出力結果は期待通りになります。

1項の2つめのサンプルについても、次のようにdone()メソッドにconsole.log()を移動すれば解決します。
<meta charset="utf-8" /><script src="http://ajax.googleapis.com/ajax/libs/jquery/1.8/jquery.min.js"></script><script>$.ajax({ url: 'test1.html',}).done(function(html) {console.log(html); console.log("foo");});</script>jQuery.ajax()ではオプションとして「async」が用意されていて、「false」を設定すると同期通信が行えるようになっています。
したがって、冒頭のサンプルを次のようにすれば実行順序を保証することができます。
<meta charset="utf-8" /><script src="http://ajax.googleapis.com/ajax/libs/jquery/1.8/jquery.min.js"></script><script>var list = new Array('test1.html', 'test2.html', 'test3.html');for (i=0; i<3; i++) { var url = list.shift(); $.ajax({ url: url,async: false }).done(function(html) { console.log(html); });}</script>なお、asyncオプションとDeferredオブジェクトの併用について、1.8では非推奨になっており、「コールバック関数(complete/success/error)を利用すること」となっているようです。
言い換えると、Deferredオブジェクトの併用でなければasyncオプションは利用可能と思われます(間違っていたらすいません)。
参考サイトは以下です。ありがとうございました。

