async是一個非常好用的模塊,祗是如果沒有高階函數的使用,用起來代碼還是相當混亂。下面是我寫的一個簡單的柯里化(部分求值)函數:
Function.prototype.curry = function () {
var appliedArgs = arguments;
var self = this;
return function () {
var j = 0;
var args = [];
for (var i = 0; i < appliedArgs.length; i++) {
if (appliedArgs[i] === undefined) {
appliedArgs[i] = arguments[j];
j ++;
}
args.push(appliedArgs[i]);
}
for (; j < arguments.length; j++) {
args.push(arguments[j]);
}
return self.apply(this, args);
};
}
例如函數:
function func(a, b, c, d, e) {
//do something
}
var f1 = func.curry('a', 'b', 'c');
f1('d', 'e')
var f2 = func.curry(undefined, 'b', 'c', undefined, 'e');
f2('a', 'd')
以後可以把控制流所有的部分抽象爲高階函數,然後通過柯里化結合async的parallel, series, waterfall等方法,即可寫出清晰可讀的複雜控制流。
23 回复
@byvoid 要并行还是串行完全看你怎么写,比如你可以了解下whenAll是做什么的,而且即便没有whenAll也可以很轻松的把需要的逻辑并行起来,随便找个Jscex介绍就会提到的。Jscex是很有背景的研究成果的JS实现,经过反复验证过的手段,不存在这些低级问题……
楼主的思路不错。
function incrAB(callback) {
async.parallel([
function(_callback) {
redis.incr('a', _callback)
}),
function(_callback) {
redis.incr('b', _callback)
})
], callback);
};
function incrAB(callback) {
async.parallel([
redis.incr.curry(redis, 'a'),
redis.incr.curry(redis, 'b')
], callback)
};
@byvoid 唉,我們都2了,ES5的bind方法就可以啊
function incrAB(callback) {
async.parallel([
redis.incr.bind(redis, 'a'),
redis.incr.bind(redis, 'b')
], callback)
};