Reputation: 8638
I'm trying to do a recursive async loop to trace all the children of a particular object from a third-party lib in nodejs.
Heres the pseudo code:
var tracer = function(nodes){
var promises [];
nodes.forEach(function(node){
// trace returns a promise ...
var promise = builder.trace(node)
promises.push(promise);
promise.then(function(tree){
// if we had children, get those
if(tree.children.length){
promises.push.apply(promises, tracer(tree.children));
}
});
});
return promises;
};
RSVP.all(tracer(myArr)).then(function(allTrees){ ... });
but I can't put my finger on how to get them all to resolve correctly and returns the results in one array.
Upvotes: 0
Views: 1068
Reputation: 664195
You must not push
the recursive promises on the array in the delayed callback. Instead, you'll need to push a promise that represents the recursive results (resolves with those delayed produced promises) right away. Luckily, you even get exactly that back from that then
call.
Additionally, I would swap out the each
for a map
, and do RSVP.all
immediately inside the function, for not expecting the caller to deal with that.
function tracer(nodes){
var promises = nodes.map(function(node){
// trace returns a promise ...
var promise = builder.trace(node)
var recusivePromise = promise.then(function(tree){
// if we had children, get those
if (tree.children.length)
return tracer(tree.children));
else
return node;// the leaf node itself
});
return recusivePromise; // which will resolve with the `tracer(…)` result
// or the leaf
});
return RSVP.all(promises);
}
tracer(myArr).then(function(allTrees){ … });
Upvotes: 4
Reputation: 8638
I ended up going with a counter type approach ...
var traceDeps = function(parents, cb){
var count = 0,
trees = [],
trace = function(nodes){
nodes.forEach(function(node){
count++;
builder.trace(node).then(function(tree){
trees.push(tree);
if(tree.children.length){
trace(tree.children);
}
count--;
if (count === 0) cb(trees);
});
});
};
trace(parents);
};
traceDeps(myArr, function(trees){ ... });
Upvotes: 0