使用回调的高阶文件夹功能

时间:2017-05-13 20:56:50

标签: javascript function reduce fold

我想编写一个给出函数列表的函数,将遍历该列表,逐步将每个闭包的结果传递给下一个闭包。

列表中函数的函数签名类似于(伪代码):

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。)

2 个答案:

答案 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)