枕を欹てて聴く

香炉峰の雪は簾を撥げて看る

Deferred.bind

これはすごい.
JSDeferred に引数束縛の bind, curry を追加 / Google Chrome の JSDeferred のインテグレーションを書いた - #生存戦略 、それは - subtech
ChromiumAPIは非同期+callback必須ばかりで, 「うわー. JSDeferred / Mochikit Deferredがないと耐えられないわー」とか思っていたのでとてもありがたいです.

で,

edvakf
引数の位置で指定するのには抵抗あるけど、「callback を引数とする関数なら何でも Deferred 化できるようになった。」はステキすぎる。

http://b.hatena.ne.jp/edvakf/20091014#bookmark-16698743

ってブックマークコメントがあって, ああこんな実装もできるなーとか思いついたのが以下.

Deferred.bind2 = function(func){
  return function(){
    var d = new Deferred();
    d.next = function(fun){
      return this._post('ok', function(){
        fun.apply(fun, (arguments[0] instanceof Deferred.ResultList) ? arguments[0].args :arguments);
      });
    }
    var args = Array.prototype.slice.call(arguments, 0);
    var callback = function(){
      d.call(new Deferred.ResultList(arguments));
    }
    var errorback = function(){
      d.fail(arguments);
    }
    Deferred.next(function(){
      func.call(this, args, callback, errorback);
    });
    return d;
  }
}

ってやると, 以下のように

var myFunc = Deferred.bind2(function(args, callback, errorback){
  setTimeout(function(){
    callback(args);
  }, 10);
});
myFunc('1', '2').next(function(args){
  console.log(args);// ['1', '2']
});

なんて書き方もできるなーということで. 自由度があがり, 引数に数字を取ったりしなくなったかわりにwrapの手間があがって
「あれっ? wrapの手間を減らすための関数だったはずでは...」
みたいな感じに.

Remove all ads