4

expressmongoose开始,我经常需要对集合进行一些批处理操作。然而,它通常涉及回调,考虑到 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);

现在我不记得在我得到一个带有 node 的 stackover 流之前的最大堆栈是多少,但我猜有 10 000 个元素,它不会这样做。我想知道是否有其他方法可以处理这个问题,如果是,它们是什么?谢谢

4

2 回答 2

5

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

一个很好的例子是async它的reduce功能

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,因此这里仅以加法为例。

于 2013-07-12T19:19:38.333 回答
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 );
于 2013-07-12T19:42:12.407 回答