jst*_*her 1 node.js async-await
我正在尝试构建一个映射给定数组的函数,然后对每个项目运行 axios 调用。完成后,我想返回映射的数组以在另一个函数中使用。
这是代码:
require('dotenv').config();
const axios = require('axios');
const consola = require('consola');
function getLeagues(listItems) {
const today = new Date();
const season = today.getMonth() >= 6 ? today.getFullYear() : today.getFullYear() - 1; // this gets the game ready for the new season every July 1st
// we will end up directly returning listItems.map once the issue is solved
const selectedLeagues = listItems.map(async (item) => {
const countryName = item.country;
const leagueName = item.league;
try {
const response = await axios({
method: 'GET',
url: `https://api-football-v1.p.rapidapi.com/v2/leagues/country/${countryName}/${season}`,
headers: {
'content-type': 'application/octet-stream',
'x-rapidapi-host': 'api-football-v1.p.rapidapi.com',
'x-rapidapi-key': process.env.FOOTY_API_KEY,
},
});
const leagueData = response.data.api.leagues
.filter((league) => league.name === leagueName)
.map((data) => {
return {
leagueId: data.league_id,
name: data.name,
seasonStart: data.season_start,
seasonEnd: data.season_end,
country: data.country,
};
})
.pop(); // we use pop() because filter() and map() return arrays and we don't want an array of 1 object, just that object
consola.ready({
// this displays all of the data as needed
// this also runs after the below consola block
message: `leagueData: ${JSON.stringify(leagueData, null, 2)}`,
badge: true,
});
return leagueData;
} catch (error) {
throw new Error(error);
}
});
consola.ready({
// this displays an array with an empty object, not an array with above leagueData object
// this also runs before the above consola block
message: `selectedLeagues: ${JSON.stringify(selectedLeagues, null, 2)}`,
badge: true,
});
return selectedLeagues;
}
module.exports = getLeagues;
Run Code Online (Sandbox Code Playgroud)
我不确定为什么在对象准备好selectedLeagues之前就返回数组。leagueData我认为 async/await 掌握了一切。相反,在我的控制台中,我得到:
selectedLeagues: [
{}
]
leagueData: {
"leagueId": 753,
"name": "Liga 3",
"seasonStart": "2019-07-19",
"seasonEnd": "2020-05-16",
"country": "Germany"
}
Run Code Online (Sandbox Code Playgroud)
我究竟做错了什么?
您必须将您的listItems.mapPromise all 函数包装起来,因为map它本身与async.
// Now magically you can add async to your map function...
Promise.all(listItems.map(async item => {
// Then put your try catch here so that it only wraps around
// the results of the function you're awaiting...
let response
try {
response = await axios()
} catch (err) {
return err;
}
// Anything else you want to do with the response...
return response
})).then(results => {
// All the resolved promises returned from the map function.
console.log(results)
})
Run Code Online (Sandbox Code Playgroud)
当您await在异步函数中使用关键字时,其余代码将只等待等待函数的结果,try catch 部分是捕获您可能遇到的任何超出您控制范围的错误,这就是为什么您只尝试 catch 周围等待的功能。
如果您在 try catch 中包含太多代码,您将无法正确诊断和处理错误。
如果您愿意,您可以在整个代码周围放置一个 try catch,但问题是,每当您遇到任何小问题时,整个代码都会出错。
您也可以使用 for of 循环来完成此操作,这可能看起来更干净......
for await (let item of listItems) {
// try catch await axios etc...
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
3778 次 |
| 最近记录: |