#javascript #mongoose #async-await
Вопрос:
Я пытаюсь получить переменную ответа, но когда вызывается функция обратного вызова, все, что я получаю, — это пустая переменная. Async/await, похоже, не работает для функции 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 " : nn" reply "```");
})
.catch(() => callback("Error: Something went wrong while getting data!"));
}
Ожидаемый вывод журнала равен 1 (23)*n раз 4, но в итоге я получаю 1 (2)*n раз 4 (3)*n раз
Комментарии:
1. Вы должны использовать
for ...of
цикл вместоforEach
цикла, чтобы обещание работало правильно
Ответ №1:
Вы либо используете обратные вызовы, либо используете Обещания. Вы пытаетесь сделать и то, и другое, когда используете await Player.findOne({ ... }, (err, player) => { ...})
.
Вы должны обновить строку, чтобы она была const player = await Player.findOne({ ... })
. Плюс, как предложил Рифат в комментарии, используйте for ...of
цикл, чтобы обещание работало правильно.
Комментарии:
1. Я согласен, код выглядит очень запутанным как с обещанием, так и с обратным вызовом. Трудно читать и отлаживать
Ответ №2:
Имеет смысл использовать 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!"));
}
Однако, чтобы снизить нагрузку на базу данных, правильным решением будет получить данные по массиву идентификаторов в одном запросе.