bsr
bsr

Reputation: 58662

Recursion using promise api

Please find the code here

http://plnkr.co/edit/zwCYGQaxyGyr7kL6fLKh?p=preview

I am trying to do recursion with an async function which uses promise. I wanted to happen it serially (so no $q.all), and want to wait till all the nodes are processed before the then of the main call to be fired. In other words, You are exited needs to be printed at the end. How can I do that?

thanks.

program

var asyncPrint = function(val) {
      var deferred = $q.defer();

      $timeout(function() {
        deferred.resolve(console.log(val));
        //console.log(val);
      }, 1000);

      return deferred.promise;
    };


 var tree = {
      1: {node:1, ch: [2,3] },
      2: {node:2, ch: [4] },
      3: {node:3, ch: [] },
      4: {node:4, ch: [5] },
      5: {node:5, ch: [] }
    }

   function recur(tre, node) {
    return Async.asyncPrint(node)
      .then(function () {
        var ch = tre[node.node] ? tre[node.node].ch : []; 
        if(ch.length > 0 ){
            angular.forEach(ch, function (d) {
                return recur(tre, tre[d])
            })
        }
      })
  }

  recur(tree, tree[1]).then(function(){
    console.log('You are exited')
  })

output

Object {node: 1, ch: Array[2]}
You are exited 
Object {node: 2, ch: Array[1]}
Object {node: 3, ch: Array[0]}
Object {node: 4, ch: Array[1]}
Object {node: 5, ch: Array[0]}

Upvotes: 0

Views: 517

Answers (1)

Bergi
Bergi

Reputation: 664538

if(ch.length > 0 ){
    angular.forEach(ch, function (d) {
        return recur(tre, tre[d])
    })
}

That doesn't work - you don't return a promise here for when you are ready with the recur calls but just return undefined. You indeed want to use all here:

return $q.all(ch.map(function(d) {
    return recur(tre, tre[d]);
});

Or, for sequentially processing the ch array:

function next(i) {
    if (i<ch.length)
        return recur(tre, tre[ch[i]]).then(next.bind(null, i+1));
    else
        return i;
}
return next(0);

Upvotes: 1

Related Questions