jQuery.Deferredについて知る

1. jQuery.Deferredとは?
jQueryバージョン1.5から導入された、非同期処理を上手に扱うたmwの標準モジュール。 javascriptで非同期処理を書くときの問題点として、 コールバック地獄と、エラー処理に例外が使えない などがある。これらを対処した。

2. jQuery.Deferredを使って書いてみる。
(before)

$.ajax({
  …,  // 経歴を入力する
  success: function () {
    // スキルシートを添付する
    $('#upload_btn').on('click', {}, function () {
      // ポートフォリオを添付する
      ga('click', {
        hitCallback: function () {
          // 経歴を入力するとスキルシートを添付とポートフォリオを添付が終わったら遷移させる
          document.location = e.target.href;
        }
      });
    });
  }
});  

!!!!!!(middle?????)!!!!!

$.ajax({}) //  経歴を入力する  
    .done(function () {
        dfdSkillsheet('click', {})   // スキルシートを添付する    
            .done(function () {
                // 経歴を入力するとスキルシートを添付が終わったら、遷移させる
                document.location = e.target.href;
             });
     })

var dfdSkillsheet = function ('event', 'props') {
    var dfd = jQuery.Deferred();  
    $('#upload_btn').on(event, props, function () {
         dfd.resolve();
    });
    return dfd.promise();  
};

階層深くなる!!よくない!
(after)

$.when(
  $.ajax({ … }),            //  経歴を入力する
  dfdSkillsheetl('click', {}), // スキルシートを添付
  dfdGa( 'click')    // ポートフォリオを添付
).done(function () {
  // 自前APIとmixpanelとGoogle Analyticsへの送信が終わったら遷移させる
  document.location = e.target.href;
}); 

並列化させる。

3. Deferredインタフェースの実装方法

var dfdfunc = function (cond) {
    var dfd = jQuery.Deferred();
    cond ?  dfd.resolve() : dfd.reject();
    return dfd.promise(); 
}  
dfdFunc(true)
  .done(function () { console.log('Resolved!'); })
  .fail(function () { console.log('Rejected!'); });  

promise#done と promise#fail はそれぞれ resolved か rejected な promise に対して実行されるコールバックを設定するメソッド!!!!

4.DeferredとPromiseの関係

  • Defferdオブジェクトが作らると、promiseは自動的に生成される。Defferdオブジェクトと非同期処理を関連付けている!!
    f:id:k_ootake:20160607094236p:plain

  • promiseだけ即座にreturn
    f:id:k_ootake:20160607094711p:plain

5. Promiseの基本構造

  • 状態(.state)
  • 状態がresolvedになったときに実行されるコールバック(.done)
  • 状態がrejectedになったときに実行されるコールバック(.fail)
var promise = delayHello(); 
promise.done(function(){/*resolvedで実行*/});  
promise.fail(function(){/*rejectedで実行*/});    

☆.then() →.doneと.failを一気にできる!

delayHello() 
.then(function(){/*resolvedで実行*/}), function(e){/*rejectedで実行*/});  

対応するコールバックのみが起動する!(resolvedになった.doneだけとか)

jQuery.Defferedでは、非同期処理それぞれにpromiseと呼ばれるオブジェクトを割り当て、そのオブジェクトの状態を伝播させていくことで処理を進める。