Skip to content

Instantly share code, notes, and snippets.

@hidachinoiro
Created April 7, 2012 00:04
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save hidachinoiro/2324162 to your computer and use it in GitHub Desktop.
Save hidachinoiro/2324162 to your computer and use it in GitHub Desktop.
Javascript で複数のコールバックをまとめて受け取る ref: http://qiita.com/items/ea576bc2a5346213a891
var Callback = (function () {
/**
* 複数のコールバックをまとめて一つのコールバックにします。
* @constructor
* @example
* var cb = new Callback();
* asyncFunc1(..., cb.here()); // f('guitar') とコールバックされる
* asyncFunc2(..., cb.here()); // f('fiddle','banjo') とコールバックされる
* asyncFunc3(..., cb.here()); // f() とコールバックされる
* asyncFunc4(..., cb.here([])); // f('mandolin') とコールバックされる
* cb.then = function(a, b, c, d) {
* // cb.here() を呼んだ数だけ引数が渡る
* // a は 'guitar'
* // b は ['fiddle', 'banjo']
* // c は null
* // d は ['mandolin']
* }
*/
var Callback = function() {
this.resultList = [];
this.stepCount = 0;
this.callCount = 0;
/**
* すべてのコールバックをまとめて最終的に呼び出される関数。
*/
this.then = null;
};
/**
* コールバック関数を生成して返す。
* 生成した関数が空引数で呼ばれた場合は null を。
* 1引数で呼ばれた場合はその値を。
* 2引数以上で呼ばれた場合は配列を登録し、
* すべてのコールバックが呼び出された時点で
* 登録した引数を then に渡して呼び出す。
* here に空配列を渡した場合は引数の数にかかわらず配列を登録する。
* @return {function(...)}
*/
Callback.prototype.here = function() {
var registerArray = arguments.length == 1 &&
arguments[0] instanceof Array &&
arguments[0].length == 0;
if (arguments.length != 0 && !registerArray) throw new Error(
"Callback#here に引数が渡されました。" +
"xx.here() と書くべき場所で xx.here としている可能性があります。");
return (function(callback, stepCount) {
return function() {
var result = arguments;
if (!registerArray && result.length == 0) {
callback.resultList[stepCount] = null;
} else if (!registerArray && result.length == 1) {
callback.resultList[stepCount] = result[0];
} else {
callback.resultList[stepCount] = [];
for (var i = 0; i<result.length; i++) {
callback.resultList[stepCount][i] = result[i];
}
}
if (++callback.callCount >= callback.stepCount) {
if (callback.then != null) {
callback.then.apply(null, callback.resultList);
Callback.call(this);
} else throw new Error("then が未登録です");
}
}
})(this, this.stepCount++);
};
return Callback;
})();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment