FM牛鍵屋本舗

プログラマ(弱)の日々精進系ブログ

Deferred模索中。とりあえずスペルややこしい。

今日試みたjQueryのDeferred

ECMA6からPromiseが言語仕様に含まれているんだっけ…。 最近流行りはObservableなんだっけ…。 そんなことを思いつつ、今日も元気にjQueryでDeferred。いつもスペルを間違える。

普段は

function hoge() {
  var $d = new $.Deferred();
  confirm($d.resolve, $d.reject);
  return $d.promise();
}

function moge() {
  hoge().done(...).fail(...);
}

みたいな書き方をしていたんですが、なんか今ひとつだなーと感じていて…。 今回、サーバ側へ状態の問い合い合わせや確認ダイアログを 数回出し、結果的に登録を行うような仕組みを仕事で実装することになり、 ちょっと違った感じに実装してみました。 正しいのかどうかまったくわかりませんが(OSSのソースでも今度眺めてみよう)。

var SaveAction = function() {
  var self = this;
  var confirmA = function() {
    var $d = new Deferred();
    confirm('保存する?', $d.resolve, $d.reject);
    $d.promise()
      .done(queryA);
  }

  var queryA = function() {
    var $d = new Deferred();
    $.ajax({
      // 中略
    })
    .done(function(result, _) {
      if (result.exists) {
        $d.resolve();
      } else {
        $d.reject();
      }
    })
    .fail(function(e) {
      console.log(e);
      $d.reject();
    });
    $d.promise()
      .done(save)
      .fail(showErrorMsg);
  }

  // 中略

  this.execute = function() {
    confirmA();
  }
}

SaveAction.execute();
// or new SaveAction().execute();

これなら各メソッドは、自分の「次に行うこと」だけを知っていて、 それを責任持って呼び出すだけという構造を作れるので割とわかりやすいかなあと。 また、クラスっぽく仕上げているので、以下のような利点があるのかなと。

  • prototypeも含めて拡張がしやすい
  • function内なので
    • リソースの共有が可能
    • 処理間の論理的なつながりを明示できる
  • 外側からexecute()キックするだけで一連の処理が走る

うーん、どうだろう…