NodeJS内部for循环的递归调用,如何知道所有调用何时完成?

时间:2017-06-22 14:33:21

标签: javascript node.js asynchronous recursion

enter image description here

我在for循环中编写一个递归函数,如下所示:

var output = [];
function myFunc(myValue, callback) {
  myAnotherFunc(myValue, function(result){
    for (var i=0; i < result.myKey.length; i++){
      if(result.myKey[i].name === 'something'){
        myFunc(result.myKey[i].recurseValue, function(recursiveResult){
          //some recursive stuff
          output.push(recursiveResult.someValue)
        });
      }
    }
  });
}

启动递归函数,如下所示:

myFunc(initialValue, function(result){
  //some stuff
});

它的工作正常,但我怎么知道我的递归流程何时结束,以便我可以从最终输出中做其他事情?

2 个答案:

答案 0 :(得分:0)

您可以使用Promises™!它基本上是一种在异步流完成之后推迟回调的方法:例如:

// Instead of passing your normal callback, we'll tell the
// function to use resolve(results) to pass your results to the 
// next code block so it can do something after all your recursions are completed
const someTask = new Promise(resolve => myFunc(initialValue, resolve))

someTask.then(result => {
  /* Do Something with the results at the end of aformentioned callback hell :D */
})

PS。您还必须将原始功能签名修改为:

function myFunc(myValue, callback) {
  myAnotherFunc(myValue, function(result){
    const cbks = [] //Store the async resuls of all myFunc() executions
    for (i=0; i < result.myKey.length; i++){
      if(results[i] === 'something'){
        cbks.push(new Promise(res => myFunc(result[i].recurseValue, res)))
      }
    }
    //Run all async myFunc() and return the results in an array
    Promise.all(cbks).then(callback)
  });
}

答案 1 :(得分:0)

function myFunc(resolve) {
  var rec = function(myVal, cb) {
    myOther(recurseValue, function(result) {
      var hasName = result[myKey].filter(function(obj) {
        return obj.name === 'something';
      })[0];
      if (hasName) {
        rec(hasName[recurseValue], function(recResult) {
          // other recursive stuff
        });
      } else {
        resolve(?); // whatever the final value should be
      }
    });
  };
  return rec;
}

function recurseAsync(f, initial) {
  return new Promise(function(resolve, reject) {
    f(resolve)(initial);
  });
}

情侣笔记。

recurseAsync函数接受一个函数,它接受一个解析回调并返回一个递归函数,该函数在完成时调用该回调来解析promise。 myFunc已被修改为符合该格式。

我使用了数组过滤而不是for循环并缩短了一些名称。此外,如果您使用变量进行对象访问,请使用[]而不是.。要在完成所有这些操作后使用最终值,您可以在承诺上调用.then

// whatever initial value 'foo' should be
var finished = recurseAsync(myFunc, foo);
finished.then(function(finalValue) {
  // do something with the final result of all the recursion
});