无法获得有条件承诺 return 最终值的递归函数

can't get recursive function with conditional promise to return final value

我遇到的问题是我需要获得对象集合的总数,它具有树的形式,其中每个对象还可以包含深层嵌套的对象。我开始的数据集合已经有一个可用的嵌套层,但要查明对象中是否有第三个或更多嵌套层,必须使用嵌套对象的 ID 进行 API 调用,returns 下一个嵌套对象(如果存在)。 所以,目前我有这样的东西:

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 promise 加载的任何内容都不包括在计数中功能。我如何让这个等到所有承诺都得到解决,以便我可以返回最终计数?

尝试从 API 调用中删除参数 "comment" 然后方法:

来自: 功能(评论){}

收件人: 函数(){}

正如 Jaromanda X 在评论中提到的,您有 getComment return 一个异步承诺,但您没有等待结果。

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

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