Promises的递归函数

时间:2017-12-30 07:12:50

标签: javascript promise

我正在使用一个返回评论对象的api,评论可以有孩子也是评论对象。

我正在尝试使用递归来检索整个注释线程,但它不起作用,只要注释没有孩子,函数就会提前结束并且返回的结果不包含整个注释线程。

如何更改功能,以便在检查完所有评论后没有孩子时解决问题。

api

返回的注释对象的示例
{
  "id": 16020433,
  "kids": [
    16021684,
    16021721,
    16021659
  ],
  "title": "Why isn't literally every train automated?",
  "type": "story"
}

这是我的代码:

function getCommentsWrapper(id) {
  let comments = [];
  return new Promise((resolve, reject) => {
    function recurseComments(id) {
      let url = `https://hacker-news.firebaseio.com/v0/item/${id}.json`;
      let comment = {};
      fetch(url)
        .then(response => response.json())
        .then(cmt => {
          comment = cmt
          comments.push(comment);
          if (comment.kids) {
            comment.kids.forEach(id => recurseComments(id));
          } else {
            resolve(comments)
          }
        })
    }

    recurseComments(id);
  })



  // call the function with
  getCommentsWrapper("16033496")
    .then(result => console.log(result));

1 个答案:

答案 0 :(得分:0)

您可以使用通话计数技术,如下面的代码所示。或者您可以使用Bluebrid等库。我认为他们有很多选择。

我认为Promise.all也可以做到这一点,但在我过去的经验中,在处理promise数组的过程中向Promise.all添加新的promise是不可靠的。

function getCommentsWrapper(id) {

  var promises = [];
  let count = 0;

  let futureValue = new Promise((resolveAll, rejectAll)=>{
      let comments = [];
      let call = (id) => {
        count++;
        new Promise((resolve, reject) => {
          let url = `https://hacker-news.firebaseio.com/v0/item/${id}.json`;
          let comment = {};
          fetch(url)
            .then(response => response.json())
            .then(cmt => {
              comment = cmt
              comments.push(comment);
              if (comment.kids) {
                comment.kids.forEach(id => call(id));
              }

              resolve();
              count--;
              if(count < 1){
                resolveAll(comments);
              }
            })
        });
      };

      call(id);
  });
  return futureValue;
}


// call the function with
getCommentsWrapper("16033496")
  .then(result => console.log(result));