我正在编写代码以从api获取数据并将其保存在mongodb数据库中。我写的代码是:
getSquadList: async (ctx) => {
var query = ctx.request.query;
var squadList = await getSquadsOfMatch(query.matchId);
if (squadList.length <= 1) {
var response = await axios.get(
`${strapi.config.currentEnvironment.getSquadListApi}?apikey=${strapi.config.currentEnvironment.cricApiKey}&unique_id=${query.matchId}`
);
squadList = response.data.squad;
var match = await Match.findOne({
unique_id: query.matchId
});
var team1Squad, team2Squad;
await squadList.forEach(async squad => {
if (squad.name === match['team-1']) {
team1Squad = {
name: match['team-1'],
match_id: match['unique_id'],
match: match['_id'],
};
await new Squad(team1Squad).save();
console.log('1');
} else if (squad.name === match['team-2']) {
team2Squad = {
name: match['team-2'],
match_id: match['unique_id'],
match: match['_id'],
};
await new Squad(team2Squad).save();
console.log('2');
}
});
squadList = await getSquadsOfMatch(query.matchId);
console.log('3');
}
ctx.send(squadList);
}
我已经使用console.log()查看执行顺序。我想要的顺序是1 2 3但实际输出是3 1 2 如何使程序最后执行这些行。 squadList =等待getSquadsOfMatch(query.matchId); console.log('3');
答案 0 :(得分:2)
如果我们模仿async
的作用,则不能将forEach
函数与forEach
一起使用:
function forEach(arr, callback){
for(let i=0;i<arr.length;i++){
callback(arr[i], i, arr);
}
}
如您所见,它不会await
回调async
。
您可以创建自定义forEach
,例如:
async function forEach(arr, callback){
for(let i=0;i<arr.length;i++){
await callback(arr[i], i, arr);
}
}
或使用简单的for
循环。
此外,您可以做的是将所有的Promise推送到一个数组中,然后调用Promise.all
处理所有请求。
async (ctx) => {
var query = ctx.request.query;
var squadList = await getSquadsOfMatch(query.matchId);
if (squadList.length <= 1) {
var response = await axios.get(
`${strapi.config.currentEnvironment.getSquadListApi}?apikey=${strapi.config.currentEnvironment.cricApiKey}&unique_id=${query.matchId}`
);
squadList = response.data.squad;
var match = await Match.findOne({
unique_id: query.matchId
});
var team1Squad, team2Squad;
const promises = squadList.map(squad => {
if (squad.name === match['team-1']) {
team1Squad = {
name: match['team-1'],
match_id: match['unique_id'],
match: match['_id'],
};
console.log('1');
return new Squad(team1Squad).save(); //returning the promise
} else if (squad.name === match['team-2']) {
team2Squad = {
name: match['team-2'],
match_id: match['unique_id'],
match: match['_id'],
};
console.log('2');
return new Squad(team2Squad).save(); //returning the promise
}
});
await Promise.all(promises); //making all the changes parallely
squadList = await getSquadsOfMatch(query.matchId);
console.log('3');
}
ctx.send(squadList);
}
注意::我写了一篇文章,介绍循环和异步函数,请随时查看https://medium.com/trappedpanda/loops-asynchronous-functions-and-returning-collective-results-in-node-js-b7566285fb74
答案 1 :(得分:0)
您可以创建一个必须首先执行的承诺数组,并在运行Promise.all
之前使用getSquadsOfMatch
等待它们解决:
getSquadList: async (ctx) => {
var query = ctx.request.query;
var squadList = await getSquadsOfMatch(query.matchId);
if (squadList.length <= 1) {
var response = await axios.get(
`${strapi.config.currentEnvironment.getSquadListApi}?apikey=${strapi.config.currentEnvironment.cricApiKey}&unique_id=${query.matchId}`
);
squadList = response.data.squad;
var match = await Match.findOne({
unique_id: query.matchId
});
var team1Squad, team2Squad;
const tasks = squadList.map(async squad => {
if (squad.name === match['team-1']) {
team1Squad = {
name: match['team-1'],
match_id: match['unique_id'],
match: match['_id'],
};
await new Squad(team1Squad).save();
console.log('1');
} else if (squad.name === match['team-2']) {
team2Squad = {
name: match['team-2'],
match_id: match['unique_id'],
match: match['_id'],
};
await new Squad(team2Squad).save();
console.log('2');
}
});
await Promise.all(tasks)
squadList = await getSquadsOfMatch(query.matchId);
console.log('3');
}
ctx.send(squadList);
}