下划线js次系列

时间:2012-05-08 00:53:06

标签: javascript node.js asynchronous backbone.js underscore.js

我正在使用带有nodejs的UnderscoreJs,并且需要_.times()方法。 times()将调用函数X次

这可以按预期工作,但我需要迭代一系列,而不是并行,这似乎正在做。

知道是否有办法在回调方法中使用它?

2 个答案:

答案 0 :(得分:3)

考虑到这样的事情:

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存在完整性,允许您在使用_.chain时添加for循环。如果你真的想要,你可能会用它来制作它,但是你会制造一个很难看的混乱而不是简化你的代码。

您可以使用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三次,那么:

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

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

这里真正的教训是,一旦你进入异步函数调用,你最终会将所有逻辑实现为回调,调用回调调用回调,回调一直向下。

答案 1 :(得分:0)

这个 async 库可能会让您入门 https://github.com/caolan/async#series

或者如果你想自己做,想法是在调用每个函数回调后进行递归调用,这里是源代码https://github.com/caolan/async/blob/master/lib/async.js#L101