jQuery.Deferred を使って、可変数の非同期処理の全ての終了を待ってから処理を実行する方法について簡単に紹介します。なお、この記事は jQuery.Deferred の記事ではなくて、どちらかというと関数オブジェクトの apply メソッドについての簡単な用法の解説になります。
クライアントサイドの Web アプリケーションで、外部 API などからデータを読み込み、その結果を待って処理を行いたい場合があります。jQuery を使うと、通常、次のように書きます。
1 2 3 |
$.ajax(url, settings).done(function(data) { //処理 }); |
ここで .done は jQuery.Deferred のメソッドで、Ajax 処理終了後に、.done で登録したコールバック関数が実行されます。
また、例えば3つの外部 API のコールが必要になって、その全ての Ajax リクエストの終了を待ってから処理を行いたい時は、次のように書けます。
1 2 3 4 5 6 7 |
var dfd1 = $.ajax(url1, settings); var dfd2 = $.ajax(url2, settings); var dfd3 = $.ajax(url3, settings); $.when(dfd1, dfd2, dfd3).done(function(data) { //処理 }); |
ここで、jQuery.when は、Deferred の為のユーティリティ関数です。when は、引数で与えられた全ての Deferred の終了(resolve)を待ってから resolve する、別の新しい Deferred を返します。返された Deferred に .done でコールバックを登録することで、3つの外部 API への Ajax リクエストの終了を待ってから、処理を行います。
さて、本題です。
では、3つではなく、1つ以上の可変数の Ajax コールの終了を待ちたいときはどのようにするでしょうか? JavaScript では、次のように書けます。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
var requests = [ { url: 'http://...', settings: { ... } }, { url: 'http://...', settings: { ... } }, { url: 'http://...', settings: { ... } } ]; var dfds = []; for (var i =0; i < requests.length; i++) { req = requests[i]; dfd = $.ajax(req.url, req.settings); dfds.push(dfd); } $.when.apply($, dfds).done(function() { //処理 }) |
これで、requests 配列に含まれる任意の数のリクエストの全ての終了を待ってから、15行目の処理が行われます。1〜5行目はデータの準備です。7〜12行目は、jQuery.ajax のコールを行って、戻り値として得られる jQuery.Deferred を dfds 配列に格納しています。14行目で全ての Ajax コールの終了を待機しています。
ポイントは14行目で、関数オブジェクトの apply を利用して、jQuery.when に対して可変数の引数でコールしています。それ以外は2つ目の例と変わりません。簡単ですね〜。 (^_^;A
もし、apply についてよく分からない場合には、次の記事にまとめたいと思いますので、お楽しみ?に、です。 (#^.^#)
§ 言い訳…
ちょっと call / apply / bind などについて資料をまとめていたのですが、その中で apply の利用例として思いつき、せっかくなので文章を追加して記事にしました。えっと…それだけです。 (^_^;A
しかし JavaScript はシンプルだなーって思いますね。はい。