javascript - Using asyncawait with a for loop for nested Axios calls - Stack Overflow

I am using Axios to perform a GET request against Facebook Graph to get the list of Facebook Pages the

I am using Axios to perform a GET request against Facebook Graph to get the list of Facebook Pages the user manages. Once I have that, then I am using a for loop to perform another GET request against Facebook Graph to pull data on each Facebook Page that the user manages. I am doing this inside of an async function with a Promise at the end to join all the data together into a single const fbProfile.

My issue is: I cannot get the results from the Axios call in const pages to populate pages array.

My code is below:

  async function getfbProfile(token) {
    try {
      const user = await axios.get('', {
        params: {
          access_token: `${token}`,
          fields: 'picture,accounts',
        },
      });
      const pages = await user.data.accounts.data.forEach((err, pageInfo) => {
        axios.get(`/${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);
    }
  }

I know that the first call goes through and the for loop calls go through. I verified the for call loop works by modifying const pages to look like below and seeing both calls successfully go to Facebook Graph.

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

I would greatly appreciate any help. I've been wracking my brains on this for the last two days. Thank you for any help you can give.

ANSWER

Thanks to Patrick Roberts for his help. Since I am using Airbnb's ESLint profile, I had to modify his example below to pass linting. Thanks again!

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

I am using Axios to perform a GET request against Facebook Graph to get the list of Facebook Pages the user manages. Once I have that, then I am using a for loop to perform another GET request against Facebook Graph to pull data on each Facebook Page that the user manages. I am doing this inside of an async function with a Promise at the end to join all the data together into a single const fbProfile.

My issue is: I cannot get the results from the Axios call in const pages to populate pages array.

My code is below:

  async function getfbProfile(token) {
    try {
      const user = await axios.get('https://graph.facebook./me', {
        params: {
          access_token: `${token}`,
          fields: 'picture,accounts',
        },
      });
      const pages = await user.data.accounts.data.forEach((err, pageInfo) => {
        axios.get(`https://graph.facebook./${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);
    }
  }

I know that the first call goes through and the for loop calls go through. I verified the for call loop works by modifying const pages to look like below and seeing both calls successfully go to Facebook Graph.

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

I would greatly appreciate any help. I've been wracking my brains on this for the last two days. Thank you for any help you can give.

ANSWER

Thanks to Patrick Roberts for his help. Since I am using Airbnb's ESLint profile, I had to modify his example below to pass linting. Thanks again!

  async function getfbProfile(token) {
    try {
      const user = await axios.get('https://graph.facebook./me', {
        params: {
          access_token: token,
          fields: 'picture,accounts',
        },
      });
      const pages = Promise.all(user.data.accounts.data.map(({ id }) => axios.get(`https://graph.facebook./${id}`, {
        params: {
          access_token: token,
          fields: 'picture,name',
        },
      })));
      const fbProfile = await Promise.all([user, pages]);
      debug(fbProfile);
    } catch (err) {
      debug(err.stack);
    }
  }
Share Improve this question edited Oct 7, 2018 at 23:51 Jeremy M asked Oct 7, 2018 at 22:48 Jeremy MJeremy M 1992 silver badges16 bronze badges 4
  • Array.forEach() returns undefined; you'll want to use Array.map() instead. – user5734311 Commented Oct 7, 2018 at 22:51
  • 1 not really related, but why do you do access_token: ${token} instead of just access_token: token – Itay Moav -Malimovka Commented Oct 7, 2018 at 22:51
  • 1 The function you're passing to map needs to return the axios.get(...) – Patrick Roberts Commented Oct 7, 2018 at 23:04
  • @ItayMoav-Malimovka I honestly can't remember, thanks for helping me make that better by not having unnecessary code in there. – Jeremy M Commented Oct 7, 2018 at 23:45
Add a ment  | 

1 Answer 1

Reset to default 2

The Promise.all() isn't necessary for user because it isn't a promise, since you've unwrapped axios.get() using await already. user.data.accounts.data.map(...) is an array of promises (after you make the fix I suggested), so you shouldn't await it directly either.

Here's a simplified approach:

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

This way, user and pages requests can occur concurrently rather than sequentially. await halts control flow until the promise is resolved, so if you have requests that don't need to be sequential, it's better to create all of them with axios.get() before awaiting all of them at once, if you can.

发布者:admin,转转请注明出处:http://www.yc00.com/questions/1745249970a4618618.html

相关推荐

发表回复

评论列表(0条)

  • 暂无评论

联系我们

400-800-8888

在线咨询: QQ交谈

邮件:admin@example.com

工作时间:周一至周五,9:30-18:30,节假日休息

关注微信