NodeJS中的递归异步循环

Recursive Async Looping in NodeJS

本文关键字:异步 循环 递归 NodeJS      更新时间:2023-09-26

我正在尝试执行递归异步循环,以从nodejs中的第三方库跟踪特定对象的所有子对象。

下面是伪代码:

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

但我无法确定如何让它们全部正确解析并在一个数组中返回结果。

您不得在延迟回调中push数组上的递归承诺。相反,您需要立即推送一个表示递归结果(使用那些延迟生成的承诺进行解析)的承诺。幸运的是,您甚至可以从那then电话中得到确切的回报。

此外,我会将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){ … });

我最终采用了计数器类型的方法......

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