jQuery.Deferred学習メモ(4)$.ajax()はPromiseを含むjqXHRオブジェクトを返す

2013-09-15

旧ブログ

t f B! P L

前の関連記事:jQuery.Deferred学習メモ(3)deferred.then()でPromise animationをreturnする


これまでみたjQuery.DeferredオブジェクトとPromise animation以外に$.ajax()もPromiseを含んだjqXHRオブジェクトを返します。

$.ajax()も$.get()も$.getJSON()も$.getScript()もPromiseを返す


 jQuery.Deferredが導入されたjQuery 1.5以降に非同期通信を行う$.ajax()はPromiseを含んだjqXHRオブジェクトというものを返すようになりました。

$.ajax()⊃$.get()⊃$.getJSON(), $.getScript()という関係なのでこれらはいずれもPromiseを返すことになります。

これらは.done(), .fail(), .always(), .then()のメソッドを使えます。

Blogger:JSONPを使ってJSON形式で引き出したブログデータを加工するで使った$.getJSON()を.done()を使って書き換えてみます。
<script src="http://code.jquery.com/jquery-1.9.1.js"></script>
<script>
$.getJSON("http://p--q.blogspot.jp/feeds/posts/default?alt=json-in-script&callback=?"
  ,function(json){
    $("#output").html("ブログ最終更新日時: "+json.feed.updated.$t+"</br>");
 });
</script>
<div id="output"></div>
これが以下のようになります。
<script src="http://code.jquery.com/jquery-1.9.1.js"></script>
<script>
$.getJSON("http://p--q.blogspot.jp/feeds/posts/default?alt=json-in-script&callback=?"
  ).done(function(json){
    $("#output").html("ブログ最終更新日時: "+json.feed.updated.$t+"</br>");
});
</script>
<div id="output"></div>
4行目でコールバック関数を第二引数で受けているか、.done()で受けているかだけの違いで動作結果は全く同じです。

jQuery.Deferred学習メモ(2)jQuery1.8以降のdeferred.then()を使うの最後にでてきたテストコード⑦を改造してsetTimeoutの変わりに$.getJSONを使って次の.always()を待たせてみます。

まずは素直にjQuery.Deferredオブジェクトを使うやり方。

テストコード⑫
<script src="http://code.jquery.com/jquery-1.9.1.js"></script>
<button id="btn1">未完</button><button id="btn2">完了</button><button id="btn3">失敗</button><br />
<div id="df_ex"></div>
<script>
var df1 = $.Deferred();
function fn1(n) {
    $( "#df_ex" ).append(df1.state()+n+"<br/>");
  }
function fn2(n) {
    var df2=$.Deferred();
    var n2;
    fn1(n);
    $.getJSON("http://p--q.blogspot.jp/feeds/posts/default?alt=json-in-script&callback=?"
      ).done(function(json){
        $( "#df_ex" ).append("ブログ最終更新日時: "+json.feed.updated.$t+"</br>");
        n2="で.alwaysも実行"; df2.resolve(n2);
        });
    return df2;
  }
df1
 .then(fn2,fn2,fn1)
 .always(fn1)
$( "button#btn1" ).on( "click", function() {
  df1.notify("で.progress実行");
});
$( "button#btn2" ).on( "click", function() {
  df1.resolve("で.done実行");
});
$( "button#btn3" ).on( "click", function() {
  df1.reject("で.fail実行");
});
</script>
「完了」ボタンをクリックするとまず「resolvedで.done実行」だけが表示されます。


$.getJSONがfeedのJSONをとってきて結果を返すまで次の.always()は実行が保留されます。

結果が出たらブログ最終更新日時と.always()の結果が表示されます。


10行目で新たにjQuery.Deferredオブジェクトdf2を作成し、18行目でそれをreturnして次の.always()に行くのを保留にしておいて、$.getJSONの結果がでてから16行目で引数をつけてdf2をresolveして保留を解除しています。

今度はjQuery.Deferredオブジェクトではなく引数だけを返してみます。

テストコード⑬
<script src="http://code.jquery.com/jquery-1.9.1.js"></script>
<button id="btn1">未完</button><button id="btn2">完了</button><button id="btn3">失敗</button><br />
<div id="df_ex"></div>
<script>
var df1 = $.Deferred();
function fn1(n) {
    $( "#df_ex" ).append(df1.state()+n+"<br/>");
  }
function fn2(n) {
    fn1(n);
    $.getJSON("http://p--q.blogspot.jp/feeds/posts/default?alt=json-in-script&callback=?"
      ).done(function(json){
        $( "#df_ex" ).append("ブログ最終更新日時: "+json.feed.updated.$t+"</br>");
        });
    return "で.alwaysも実行";
  }
df1
 .then(fn2,fn2,fn1)
 .always(fn1)
$( "button#btn1" ).on( "click", function() {
  df1.notify("で.progress実行");
});
$( "button#btn2" ).on( "click", function() {
  df1.resolve("で.done実行");
});
$( "button#btn3" ).on( "click", function() {
  df1.reject("で.fail実行");
});
</script>
「完了」ボタンをクリックすると先ほどと違ってブログ最終更新日時の結果表示を待たずに.always()の結果が表示されているのがわかります。


今度は$.getJSONをreturnしてみます。

テストコード⑭
<script src="http://code.jquery.com/jquery-1.9.1.js"></script>
<button id="btn1">未完</button><button id="btn2">完了</button><button id="btn3">失敗</button><br />
<div id="df_ex"></div>
<script>
var df1 = $.Deferred();
function fn1(n) {
    $( "#df_ex" ).append(df1.state()+n+"<br/>");
  }
function fn2(n) {
    fn1(n);
    return $.getJSON("http://p--q.blogspot.jp/feeds/posts/default?alt=json-in-script&callback=?"
      ).done(function(json){
        $( "#df_ex" ).append("ブログ最終更新日時: "+json.feed.updated.$t+"</br>");
        });
  }
df1
 .then(fn2,fn2,fn1)
 .always(fn1)
$( "button#btn1" ).on( "click", function() {
  df1.notify("で.progress実行");
});
$( "button#btn2" ).on( "click", function() {
  df1.resolve("で.done実行");
});
$( "button#btn3" ).on( "click", function() {
  df1.reject("で.fail実行");
});
</script>
「完了」ボタンをクリックすると.always()は$.getJSONの結果を待ってから実行されています。

引数が.then()では返されていないのはPromise animationのときと同じですね。


この問題は$.when()を使って解決できました。

jQuery.Deferred学習メモ(5)jQuery.when()で複数PromiseのAND条件を判定のテストコード⑱へ。

参考にしたサイト


jQuery.ajax() | jQuery API Documentation
$.ajax()の本家の解説。

次の関連記事:jQuery.Deferred学習メモ(5)jQuery.when()で複数PromiseのAND条件を判定

ブログ検索 by Blogger

Translate

最近のコメント

Created by Calendar Gadget

QooQ