javascript - 将 async/await 与 for 循环一起用于嵌套的 Axios 调用
问题描述
我正在使用 Axios 对 Facebook Graph 执行 GET 请求,以获取用户管理的 Facebook 页面列表。一旦我有了它,我就会使用 afor loop
对 Facebook Graph 执行另一个 GET 请求,以在用户管理的每个 Facebook 页面上提取数据。我在async function
aPromise
中执行此操作,最后将所有数据连接到一个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);
});
});
我将不胜感激任何帮助。这两天我一直在为此绞尽脑汁。感谢您提供的任何帮助。
回答
感谢帕特里克·罗伯茨的帮助。由于我使用的是 Airbnb 的 ESLint 配置文件,因此我必须修改下面的示例以通过 linting。再次感谢!
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);
}
}
解决方案
ThePromise.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
暂停控制流直到promise被解决,所以如果你有不需要顺序的请求,如果可以的话,最好用axios.get()
beforeawait
一次创建所有请求。
推荐阅读
- r - 在 R 的 geosphere 包中,为什么轴承不在 0-360 度?
- json - 在 json 中创建一个具有真或假响应的 ping
- python - 广播 - 给定矩阵基础的 3D 系数场到矩阵的 3D 场
- github - 为什么 GitHub 继续推送 Pipfile 中使用的不同版本?
- firebase - 通过控制台更新 Firestore 中的字符串字段
- ios - ==44088==错误:AddressSanitizer:堆栈缓冲区溢出
- angular - 带有 Webpack 4 的 Angular 6-cli
- c++ - shared_ptr 对象上的 dynamic_cast
- magento2 - Magento 2 的全新安装 - 商店加载正常,管理员登录失败并出现 CURLPROTO_HTTP 错误
- typo3 - 使用flux:field.inline.fal时如何获取fal对象而不是数组