简体   繁体   English

NodeJS 中的递归异步循环

[英]Recursive Async Looping in NodeJS

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.我正在尝试执行递归异步循环,以从 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.但我无法确定如何让它们全部正确解析并在一个数组中返回结果。

You must not push the recursive promises on the array in the delayed callback.您不得在延迟回调中将递归承诺push送到数组上。 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.幸运的是,你甚至可以准确地从那个后面then调用。

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.此外,我会将each换成map ,并立即在函数内部执行RSVP.all ,因为不希望调用者处理它。

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){ … });

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){ ... });

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM