我正在将UnderscoreJs与nodejs一起使用,并且需要_.times()方法。 times()将调用一个函数X次

这可以按预期工作,但是我需要进行一系列的迭代,而不是并行进行迭代。

知道是否可以使用带有回调方法的系列方法吗?

最佳答案

给定这样的东西:

function f() {
    some_async_call({ callback: function(err, results) {...})
}
_(3).times(f);


然后,三个f调用将串行发生,但some_async_call调用不一定是串行发生的,因为它们是异步的。

如果要强制您的调用按顺序运行,则需要使用异步调用上的回调来启动该系列中的下一个:

function f(times, step) {
    step = step || 0;
    some_async_call({
        callback: function(err, results) {
            // Do something with `err` and `results`...
            if(step < times)
                f(times, step + 1);
        }
    });
}
f(3);


该方法将依次执行三个some_async_calls,但是,很遗憾,初始f(3)将立即返回。当然,解决该问题的一种方法是另一种回调:

function f(from_n, upto, and_finally) {
    some_async_call({
        callback: function(err, results) {
            // Do something with `err` and `results`...
            if(from_n < upto)
                f(from_n + 1, upto, and_finally);
            else
                and_finally();
        }
    });
}
f(0, 3, function() { console.log('all done') });


_.times放在哪里?真的没有。 _.times is just a for loop

_.times = function(n, iterator, context) {
  for (var i = 0; i < n; i++) iterator.call(context, i);
};


_.times存在是为了完整性,并允许您在使用for时添加_.chain循环。如果您确实愿意,可以穿上它,但是这样做只会使您一团糟,而不是简化代码。

您可以使用250R的异步思想,但必须构建三个函数的数组,但是_.range_.map_.times更适合此功能:

// Untested off the top of my head code...

function f(callback) {
    some_async_call({
        callback: function(err, results) {
            // Deal with `err` and `results`...
            callback();
        }
    });
}

var three_fs = _(3).range().map(function() { return f });
async.series(three_fs);


但是您仍然必须修改f以具有回调函数,并且如果您始终总是调用f 3次,则:

async.series([f, f, f]);


可能比使用_.range_.map动态构建阵列更好。

真正的教训是,一旦您进入异步函数调用,您最终将所有逻辑实现为回调,回调,回调,回调。

10-07 19:58
查看更多