Рекурсивная функция с обещаниями

1

Я использую 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));
Теги:
promise

1 ответ

0
Лучший ответ

Вы можете использовать метод подсчета вызовов, как в приведенном ниже коде. Или вы можете использовать библиотеку, такую как Bluebrid. Я думаю, у них много вариантов.

Я думаю, что Promise.all может сделать все необходимое, но в моем прошлом опыте, добавляя новые обещания Promise.all, в то время как массив обещаний обрабатывается, не был надежным.

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));
  • 0
    Спасибо, добавив переменную count, чтобы отследить, сколько раз вложенные комментарии отлично работают. Какова причина создания дополнительного Обещания, чтобы обернуть Обещание, делая выборку?
  • 0
    Таким образом, вы можете следовать шаблону then, который есть в вашем коде, как в getCommentsWrapper. В противном случае вам нужно будет создать обратный вызов.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню