我正在尝试获取回复变量,但是当调用回调函数时,我得到的只是一个空变量。异步/等待似乎不适用于 findOne 功能,因为我在调用回调后获取值。
function byClanTag(tag, callback) {
clashApiClient
.clanByTag(tag)
.then((response) => {
var reply = "";
console.log("1");
response.memberList.forEach(async (member) => {
console.log("2");
await Player.findOne({ playerTAG: member.tag }, (err, player) => {
if (err) {
console.log(err);
callback("Error: ", err);
}
if (!player) {
console.log("3");
reply = reply + member.name + ": " + "Strike information doesn't exist.\n";
} else {
reply = reply + member.name + ": " + player.strikeCount + "Strikes.\n";
}
});
});
console.log("4");
callback("```" + response.name + " : \n\n" + reply + "```");
})
.catch(() => callback("Error: Something went wrong while getting data!"));
}
预期的日志输出是 1 (23)*n 次 4 但我最终得到 1 (2)*n 次 4 (3)*n 次
答案 0 :(得分:3)
您要么使用回调,要么使用 Promise。当您使用 await Player.findOne({ ... }, (err, player) => { ...})
时,您正在尝试同时执行这两项操作。
您应该将行更新为 const player = await Player.findOne({ ... })
。另外,正如 Rifat 在评论中所建议的那样,使用 for ...of
循环使承诺正常工作。
答案 1 :(得分:1)
使用 Promise.all 并行而不是像这样串行发出所有请求是有意义的:
function byClanTag(tag, callback) {
clashApiClient
.clanByTag(tag)
.then((response) => {
const pendingPromises = response.memberList.map((member) => Player.findOne({ playerTAG: member.tag })
return Promise.all(pendingPromises)
})
.then((arrayOfResults) => {....})
.catch(() => callback("Error: Something went wrong while getting data!"));
}
但是,为了减少数据库的负载,正确的解决方案是在一个请求中通过一组 ID 获取数据。