无法获得具有条件承诺的递归函数来返回最终值

时间:2017-04-17 04:12:10

标签: javascript recursion promise angular-promise

我遇到的问题是我需要获得一个对象集合的总数,它具有树的形式,其中每个对象也可以包含深层嵌套的对象。我开始的数据集合已经有一个嵌套层可用,但是为了找出对象中是否存在第三个或更多嵌套层,必须使用嵌套对象的id进行API调用,该id返回下一个嵌套对象如果它存在 所以,目前我有这样的事情:

function getCount(thread) {
  var deferred = $q.defer();
  var count = 0;
  function getComment(comment) {
    count++;

//if nested comments exist in data
    if (comment.fld.nested) {
      _.each(comment.fld.nested, function(x) {
        getComment(x);
      });
      deferred.resolve(count);

    } else if (comment.meta) {

//if not, load more from API with id
      return PostService.getComment(comment.meta.id).then(function(comment){
        if (comment.fld.nested) {
          _.each(comment.fld.nested, function(x) {
            return getComment(x);
          });
        }
        return count;
      });
    }
    return deferred.promise;
  }
  _.each(thread.fld.nested, function(x) {
    return getComment(x);
  });
return deferred.promise;
}


getCount(c).then(function(x) {
  console.log('final count:', x);
});

现在,我可以获得嵌套到第二级深度的所有对象的计数,但是当我调用getCount()。then()函数时,从API承诺加载的任何内容都不包含在计数中。如何解决所有承诺,以便我可以获得最终的计数?

2 个答案:

答案 0 :(得分:0)

尝试从API调用中移除参数“comment”,然后方法:

自: 功能(评论){}

要: 函数(){}

答案 1 :(得分:0)

正如Jaromanda X在评论中提到的,你有getComment返回异步承诺,但你不是在等待结果。

阻碍你的一个方面是你正在使用延迟式的承诺;如果你使用then,你将能够在then处理程序中返回一个promise,这将导致外部承诺等待内部承诺。

// foo won't resolve until Promise Two resolves.
var foo = getPromiseOne().then(function(valueOne) {
  return getPromiseTwo(valueOne);
});

你会等待许多并行的承诺,所以我将切换到Promise.all$q.all)和Array.map_.map)所以很清楚你在等什么。

function getCount(thread) {
  var count = 0;
  function getComment(comment) {
    count++;

//if nested comments exist in data
    if (comment.fld.nested) {
      return $q.all(_.map(comment.fld.nested, function(x) {
        return getComment(x);
      }));
    } else if (comment.meta) {

//if not, load more from API with id
      return PostService.getComment(comment.meta.id).then(function(comment){
        if (comment.fld.nested) {
          return $q.all(_.map(comment.fld.nested, function(x) {
            return getComment(x);
          }));
        }
      });
    }
    return;  // Count matters, not return values, so returning undefined is fine.
  }

  // Wait for all nested promises to resolve, but ignore the array result
  // and return the count instead.
  return $q.all(_.map(thread.fld.nested, function(x) {
    return getComment(x);
  }).then(function() { return count; });
}

getCount(c).then(function(x) {
  console.log('final count:', x);
});