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));
    }
  };
};
  • Вопрос задан
  • 90 просмотров
Решения вопроса 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));
    }
  };
};
Ответ написан
Пригласить эксперта
Ваш ответ на вопрос

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

Войти через центр авторизации
Похожие вопросы
Admitad Projects Москва
от 130 000 до 200 000 ₽
Fundraise Up Санкт-Петербург
от 2 500 до 3 500 $
от 5 000 до 6 500 $
28 мая 2020, в 19:31
200000 руб./за проект
28 мая 2020, в 19:04
4000 руб./за проект
28 мая 2020, в 18:31
1000 руб./за проект