Mesuti
@Mesuti

Как проще оформить промис с вложенным перебором промисов?

Привет.

Нужно через fetch получить главный список данных.
Из него также получаю список ссылок, через их перебор и fetch в цикле получаю доп.данные.
И результат отправляется в state.

НО по итогу state пустой, где-то промис теряется.
Как правильно и как проще оформить такую цепочку промисов с вложенным перебором fetch и гарантированно получить результат с сохранением в state?

У меня сейчас примерно такой нерабочий код:
function dataPage() {
        let fetchObject;  // Главный контейнер, в конце его запишем в state
        fetch('example.com') // Главный сайт
            .then(response => response.json())
            .then(data => {
                fetchObject = data; // Сохраняем главный результат
                fetchObject.arr = []; // Создаем массив, чтобы сюда сохранить список 
                data.URLs.map(url => { // Перебираем список URL из главного результата
                    fetch(url) // Запрашиваем данные с каждого url 
                        .then(response => response.json())
                        .then(data => {
                            fetchObject.arr.push(data) // Сохраняем доп.данные
                        })
                })
            })
            .then(() => {
                // Сохраняем все результаты в state
                setState(prevState => {
                    return (
                        {
                            ...prevState,
                            fetchObject
                        }
                    )
                })
            })
    }
  • Вопрос задан
  • 174 просмотра
Решения вопроса 2
profesor08
@profesor08 Куратор тега JavaScript
Вот чтоб не путаться и не ломать голову в бесконечных колбеках, ввели асинхронные функции.

Комментариев к коду не будет, тут все очевидно и в комментариях не нуждается.
async function loadData() {
  const response = await fetch("example.com");
  const data = await response.json();
  const links = await Promise.all(data.URLs.map(async (url) => {
    const urlResponse = await fetch("example.com");
    return await urlResponse.json();
  }));

  setState((prevState) => ({
    ...prevState,
    fetchObject: {
      ...data,
      URLs: links,
    },
  }));
}
Ответ написан
miraage
@miraage
Старый прогер
function dataPage() {
  fetch('example.com')
    .then(response => response.json())
    .then(data => {
      const promises = data.URLs.map(url => fetch(url).then(r => r.json()))

      return Promise.all(promises).then((arr) => {
        data.arr = arr;
        return data;
      })
    })
    .then((data) => {
      setState(prevState => {
        return (
          {
            ...prevState,
            data // вероятно тут спред нужен по логике
          }
        )
      })
    })
}
Ответ написан
Пригласить эксперта
Ответы на вопрос 1
Alexandroppolus
@Alexandroppolus
кодир
К прочтению:
Promise.all
Promise.allSettled
async/await

Как разберёшься, всё моментально станет понятно
Ответ написан
Комментировать
Ваш ответ на вопрос

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

Войти через центр авторизации
Похожие вопросы