简体   繁体   中英

NodeJS recursive call inside for loop, how to know when all calls are done?

在此处输入图片说明

I am writing a recursive function inside for loop like below:

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

And initiating the recursive function like below:

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

Its working fine, but how do I know when my recursive flow ends so that I can do something else from the final output?

You can use Promises™! It's basically a way to defer a callback till after an Asynchronous flow is completed: Example:

 // 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. You also have to modify your original function signature to:

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

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

Couple notes.

The recurseAsync function takes a function that takes a resolution callback and returns a recursive function that calls that callback when finished to resolve the promise. myFunc has been altered to fit that format.

I used array filtering rather than a for loop and shortened some names. Also if you are using a variable for object access use [] instead of . . To use the final value when all of this is finished you can call .then on the promise.

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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