jQuery 1.5のDeferredって何?

jQuery1.5がいつの間にかリリースされていた。1.5ではAjax関係のコードが書き直され、コールバック関数をsuccessメソッドの引数として指定できるようになったらしい。

$.ajax({
    url: "/test.txt", 
    cache: false, 
    dataType:"text"
}).success(function(data){ 
    alert(data)
});

このコード、ajaxリクエスト実行してからコールバックを設定しているように見える。ajaxリクエストは非同期実行で、ネットワークアクセスの遅延があるので、successメソッドのコールバック設定の方が先に実行されるのかもしれないが、いくらなんでもそんな確実性のない設計はありえない。というわけで、その辺を上手くやってくれるのが1.5で追加されたDeferredという機能。

jQuery 1.5のajaxメソッドはDeferredというオブジェクトを返す。ajaxリクエストが完了すると、Deferredにajaxレスポンスが貯められ、リクエストが完了した後でもsuccessやerrorのコールバックを設定できるのだ。次のコードを試してみると分かりやすい。

https://nullpon.moe/dev/sample/jquery/deferred/

$(function() {
  var deferred;
  
  $("#ajax").click(function() {
    deferred = $.ajax({
      url: "test.txt", 
      dataType: "html",
    });
  });

  $("#callback").click(function() {
    if (!deferred) {
      return;
    }
    deferred.success(function(data) {
      $("#data").text(data);
    });
  });
});

しかし、コールバックを別メソッドで設定できる以外に何に使うんだろねコレ?

Deferredは自分で作って使うこともできる。resolveでデータを受け取り、doneで設定したコールバックが呼び出される。データを渡すのが先でもコールバックを設定するのが先でも、どちらでも構わない。

$.Deferred().done(function(arg){ alert(arg) }).resolve("hoge");
$.Deferred().resolve("fuga").done(function(arg){ alert(arg) });