Задать вопрос

Как сделать рекурсивный последовательный async-await?

Нужно строго последовательно выполнить серию асинхронных запросов и полученные данные запушить в массив. Исходные данные имеют древовидную структуру:

let data = [{
  url: '/some-url',
  children: [
    {
      url: 'some-url',
      children: null
    },
    {
      url: 'some-url',
      children: [
        {
          url: 'some-url',
          children: null
        }
      ]
    }
  ]
},
{
  url: 'some-url',
  children: null
}]

Требуется написать цикл, который рекурсивно обрабатывать массив, делая запросы на url'ы. Т.е., при первой итерации делает запрос, дожидается ответа, пушит ответ в массив, затем проверяет, если ли у объекта на данном уровне children, если есть, то делает всё то же самое с children'ами. Иначе говоря, на выходе должен получиться одномерный массив с данными, полученными по урлам. Использую axios в vue-приложении, т.е. запросы делаются this.axios.get(url).
Как лучше всего решить подобную задачу?
  • Вопрос задан
  • 904 просмотра
Подписаться 1 Простой 1 комментарий
Помогут разобраться в теме Все курсы
  • Нетология
    Веб-разработчик с нуля: профессия с выбором специализации
    14 месяцев
    Далее
  • Яндекс Практикум
    Фронтенд-разработчик расширенный
    13 месяцев
    Далее
  • Skillbox
    JavaScript
    3 месяца
    Далее
Решения вопроса 1
0xD34F
@0xD34F Куратор тега JavaScript
const fetchOne = url => axios
  .get(url)
  .then(r => r.data)
  .catch(err => err);

Рекурсия есть:

async function fetchNested(data) {
  const result = [];

  if (Array.isArray(data)) {
    for (const n of data) {
      result.push(await fetchOne(n.url), ...await fetchNested(n.children));
    }
  }

  return result;
}

Рекурсии нет:

const fetchNested = async function(data) {
  const result = [];
  const stack = [];

  for (let [ i, arr ] = this(data); ++i < arr.length || stack.length;) {
    if (i === arr.length) {
      [ i, arr ] = stack.pop();
    } else {
      result.push(await fetchOne(arr[i].url));
      stack.push([ i, arr ]);
      [ i, arr ] = this(arr[i].children);
    }
  }

  return result;
}.bind(x => [ -1, x instanceof Array ? x : [] ]);
Ответ написан
Пригласить эксперта
Ответы на вопрос 1
@AndrewRusinas
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы