BenderIsGreat34
@BenderIsGreat34
junior front-end

Почему код выполняется асинхронно в конструкции async/await?

Есть функция, которая вызывается в компоненте, я получаю название фильма, он может быть либо в массиве (несколько фильмов), либо один фильм строкой.
Ожидается, что если передаётся массив, то запускаем метод map, он пробегается по каждому названию фильма и вызывает на каждый айтем асинхронную функцию, которая обращается к апи, собирает все нужные данные, а после передаёт это в массив. После чего мы передаём массив в экшен и где он обрабатывается.
Но по итогу в экшен прилетает пустой массив, а консоль логи выводятся в таком порядке: второй консоль лог, первый консоль лог. То есть массив не успевает наполниться, а мы уже его отправляем в экшен. Почему так происходит, если я использую async/await?
export const getDataMovie = (filmName) => {
  return async (dispatch) => {
    const movieData = await [];

    const getData = async (film) => {
      let resp = await fetch(
        `http://www.omdbapi.com/?t=${film}&apikey=...`
      );
      resp = await resp.json();
      const title = await resp.Title;
      const year = await resp.Year;
      const genre = await resp.Genre;
      await movieData.push({ title, year, genre });
      await console.log(movieData);  // первый консоль
    };

    if (Array.isArray(filmName)) {
      await filmName.map((item) => getData(item));
      await console.log(movieData);  // второй консоль
      await dispatch(getFavoriteMovie(movieData));
    } else {
      await getData(filmName);
      await dispatch(getFavoriteMovie(movieData));
    }
  };
};
  • Вопрос задан
  • 122 просмотра
Решения вопроса 1
BenderIsGreat34
@BenderIsGreat34 Автор вопроса
junior front-end
Отвечу за тех токсиков, что понабежали в комментарии.
Проблема была в том, что метод мап запускаеся и код выполняется дальше.
Чтобы это исправить я делаю обработку цикла параллельно при помощи Promise.all(), куда передаю необходимые промисы. За наводку спасибо @notiv-nt
export const getDataMovie = (filmName) => {
  const movieData = [];
  async function getData(film) {
    let resp = await fetch(`http://www.omdbapi.com/?t=${film}&apikey=...`);
    resp = await resp.json();
    const title = await resp.Title;
    const year = await resp.Year;
    const genre = await resp.Genre;
    movieData.push({ title, year, genre });
  }
  return async (dispatch) => {
    // делаем проверку на массив, потому что в компоненте favorite
    // мы передаем массив названий фильмов
    if (Array.isArray(filmName)) {
      const result = filmName.map((item) => getData(item));
      console.log(result);

      await Promise.all(result);
      dispatch(getFavoriteMovie(movieData));
    } else {
      getData(filmName);
      dispatch(getFavoriteMovie(movieData));
    }
  };
};
Ответ написан
Пригласить эксперта
Ваш ответ на вопрос

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

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