Tell me more ×
Stack Overflow is a question and answer site for professional and enthusiast programmers. It's 100% free, no registration required.

Beginning with express and mongoose i often need to do some batch operations on collections. However it usually involves callbacks which is a pain given how concurrency is coded in nodejs. so basically

//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);

Now i dont remember what is the max stack before i get a stackover flow with node , but i guess with 10 000 elements , it wont do. I wonder if there are other ways to handle this, if yes , what are they? thanks

share|improve this question
1  
Well, asynchronous functions will help with stack overflows as the callback will be in a different call stack. But, by breaking out into a different stack, it renders return rather useless. – Jonathan Lonowski yesterday
1  
take a look at async – go-oleg yesterday

2 Answers

If the goal is to iterate an collection asynchronously, there are numerous control flow libraries available.

A good example is async and its 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) {
    // ...
});

Note: It's not entirely clear what value you wanted to get from doRecursion, so this just uses addition for an example.

share|improve this answer
I know async. does async has a way to generalize recursion so recursion can be written in a "prettier" fashion ? People are telling me there should be no stackoverflow issue with recursion and async calls, i need to test it to be sure. EDIT : i see you are using Async.reduce , interesting ,did not know about that one. – mpm yesterday

i think you can simply self-iterate instead of true recursion, since you're not drilling into a deep object:

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

doRecursive(C);

this does not create a tall stack if the code functions as labeled. i localized C so that it executes faster and is potentially re-usable on other collections. the pattern also makes it easy to defer it for long-running operations, just by changing

doRecursive(C, ++i);

to

setTimeout( doRecursive.bind(this, C, ++i), 50 );
share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.