我想编写一个给出函数列表的函数,将遍历该列表,逐步将每个闭包的结果传递给下一个闭包。
列表中函数的函数签名类似于(伪代码):
typealias DoneClosure = (Dictionary) -> Void
typealias Middleware = (Dictionary, DoneClosure) -> Void
我会有一个类型Middleware
的列表,我想从左到右缩小,在列表中折叠并将每个闭包的结果传递给下一个闭包。
let middleware1 = { acc, done in
// do something with acc, modify it
done(acc)
}
每个函数看起来都与此类似,它们会以某种方式修改累加器,然后将结果传递给done或next函数。
我正在寻找的是一个递归函数,它可以使用回调在列表中折叠,因此可以处理异步。谁能帮我吗? (语言无关紧要,但首选JS或Swift。)
答案 0 :(得分:3)
// does not handle empty middlewareList
const makeFunctionChain = function (middlewareList, initalDic) {
const length = middlewareList.length;
let i = 0;
let middleware;
const next = function (localAccumulator) {
middleware = middlewareList[i];
i += 1;
if (i === length) {
// there is no next
// pass a do-nothing function
middleware(localAccumulator, function() {});
} else {
middleware(localAccumulator, next);
}
};
next(initalDic);
};
// usage example
const middlewareAddOnions = function (food, next) {
// simple middleware
food["onions"] = 3;
next(food);
};
const middlewareAddWater = function (food, next) {
// here we use a new accumulator
const newFood = Object.assign({}, food, {withWater: true});
next(newFood);
};
const middlewareCook = function (food, next) {
// next can also be called asynchronously.
// here we use setTimeout
const timeToCook = 1500;
setTimeout(function () {
food.cooked = true;
next(food);
}, timeToCook);
};
const middlewareServe = function (food, next) {
// here we read the data
// does not use next
if (food.cooked) {
console.log(`Time to eat: ${JSON.stringify(food)}`);
} else {
console.log(`Something went wrong: ${JSON.stringify(food)}`);
}
};
// time to try it out
const food = {
eggs: 4,
potatoes: 12,
// ...
};
makeFunctionChain([
middlewareAddOnions,
middlewareAddWater,
middlewareCook,
middlewareServe
], food);
如评论中所述,还有可能使用Promises获得类似的结果。
答案 1 :(得分:0)
我能够使用递归(在Swift中)找出它
with tf.name_scope('loss'):
cost = tl.cost.cross_entropy(y,y_,name='softmaxloss')
tf.summary.scalar("loss", cost)
with tf.name_scope('accuracy'):
correct_pred = tf.equal(tf.argmax(y,1),y_)
acc = tf.reduce_mean(tf.cast(correct_pred,tf.float32))
tf.summary.scalar("accuracy", acc)
tl.utils.fit(sess,network,train_op,cost,X_train,y_train,x,y_,acc=acc,batch_size=256,
n_epoch=200,print_freq=1,X_val=X_val, y_val=y_val,eval_train=False,tensorboard=True)