Использование async / await с циклом for для вложенных вызовов Axios - PullRequest
0 голосов
/ 08 октября 2018

Я использую Axios для выполнения запроса GET к Facebook Graph, чтобы получить список страниц Facebook, которыми управляет пользователь.Получив это, я использую for loop для выполнения другого запроса GET к Facebook Graph для извлечения данных на каждой странице Facebook, которой управляет пользователь.Я делаю это внутри async function с Promise в конце, чтобы объединить все данные в один const fbProfile.

Моя проблема: Я не могу получитьрезультаты вызова Axios в const pages для заполнения массива pages.

Мой код ниже:

  async function getfbProfile(token) {
    try {
      const user = await axios.get('https://graph.facebook.com/me', {
        params: {
          access_token: `${token}`,
          fields: 'picture,accounts',
        },
      });
      const pages = await user.data.accounts.data.forEach((err, pageInfo) => {
        axios.get(`https://graph.facebook.com/${user.data.accounts.data[pageInfo].id}`, {
          params: {
            access_token: `${token}`,
            fields: 'picture,name',
          },
        });
      });
      const fbProfile = await Promise.all([user, pages]);
      debug(fbProfile);
    } catch (err) {
      debug(err.stack);
    }
  }

Я знаю, что первый вызов проходит, и вызовы цикла forпроходить через.Я проверил работоспособность цикла for call, изменив const pages, чтобы он выглядел так, как показано ниже, и убедившись, что оба вызова успешно идут в Facebook Graph.

  const pages = await user.data.accounts.data.forEach((err, pageInfo) => {
    axios.get(`https://graph.facebook.com/${user.data.accounts.data[pageInfo].id}`, {
      params: {
        access_token: `${token}`,
        fields: 'picture,name',
      },
    })
      .then((result) => {
        debug(result);
      });
  });

Я был бы очень признателен за любую помощь.Я ломал голову над этим последние два дня.Спасибо за любую помощь, которую вы можете оказать.

ОТВЕТ

Спасибо Патрику Робертсу за его помощь.Поскольку я использую профиль ESLint от Airbnb, мне пришлось изменить приведенный ниже пример, чтобы пропустить пометку.Еще раз спасибо!

  async function getfbProfile(token) {
    try {
      const user = await axios.get('https://graph.facebook.com/me', {
        params: {
          access_token: token,
          fields: 'picture,accounts',
        },
      });
      const pages = Promise.all(user.data.accounts.data.map(({ id }) => axios.get(`https://graph.facebook.com/${id}`, {
        params: {
          access_token: token,
          fields: 'picture,name',
        },
      })));
      const fbProfile = await Promise.all([user, pages]);
      debug(fbProfile);
    } catch (err) {
      debug(err.stack);
    }
  }

1 Ответ

0 голосов
/ 08 октября 2018

Promise.all() не требуется для user, потому что это не обещание, поскольку вы развернули axios.get(), используя await.user.data.accounts.data.map(...) - это массив обещаний (после того, как вы сделаете исправление, которое я предложил ), поэтому вы не должны await делать это напрямую.

Вотупрощенный подход:

async function getfbProfile(token) {
  try {
    const user = axios.get('https://graph.facebook.com/me', {
      params: {
        access_token: token,
        fields: 'picture,accounts',
      },
    });
    const pages = Promise.all(user.data.accounts.data.map(({ id }) => {
      return axios.get(`https://graph.facebook.com/${id}`, {
        params: {
          access_token: token,
          fields: 'picture,name',
        },
      });
    }));
    const fbProfile = await Promise.all([user, pages]);
    debug(fbProfile);
  } catch (err) {
    debug(err.stack);
  }
}

Таким образом, user и pages запросы могут выполняться одновременно, а не последовательно.await останавливает поток управления до тех пор, пока не будет выполнено обещание, поэтому, если у вас есть запросы, которые не должны быть последовательными, лучше создать все из них с помощью axios.get() до await одновременного их выполнения, если выможет.

...