nodejs中的异步和递归

时间:2013-07-12 18:58:01

标签: javascript node.js mongodb express mongoose

express mongoose 开始,我经常需要对集合执行一些批处理操作。 然而,它通常涉及回调,这对于如何在nodejs中编码并发而言是一种痛苦。 所以基本上

//given a collection C 
var i = 0;
var doRecursive = function(i){
    if(i<C.length){
      C[i].callAsync(err,result){
        i=+1;
        return doRecursive(i);
       }
    }else{
      return done();
    }
}
doRecursive(i);

现在我不记得在获得带节点的堆栈流之前什么是最大堆栈,但我想有10 000个元素,它不会这样做。 我想知道是否还有其他方法可以解决这个问题,如果是的话,它们是什么? 感谢

2 个答案:

答案 0 :(得分:5)

如果目标是异步迭代集合,则可以使用许多控制流库。

一个很好的例子是async及其reduce function

async.reduce(C, 0, function (memo, item, callback) {
    item.callAsync(function (err, result) {
        if (err) {
            callback(err);
        } else {
            callback(null, memo + result);
        }
    });
}, function (err, result) {
    // ...
});

注意:您想要从doRecursion得到什么价值并不完全清楚,所以这只是使用加法作为示例。

答案 1 :(得分:1)

我认为你可以简单地自我迭代而不是真正的递归,因为你没有钻进深层对象:

function doRecursive (C, i){
    i=i||0;
    if(i<C.length){
       C[i].callAsync(err, function(result){
          doRecursive(C, ++i);
       });
    }else{
       done();
    }
};

doRecursive(C);

如果代码的功能与标签相同,则不会创建高堆栈。 我本地化了C,因此它执行得更快,并且可能在其他集合上可重复使用。 通过更改

,该模式还可以轻松地将其推迟到长时间运行的操作中
doRecursive(C, ++i);

setTimeout( doRecursive.bind(this, C, ++i), 50 );