@CK1002

Почему пустой массив после запроса в базу данных sqlite?

// players = [ ]
try {
        let players = [];
        const kills = message.guild.emojis.cache.find(emoji => emoji.name === "kills"),
            damage = message.guild.emojis.cache.find(emoji => emoji.name === "damage");
        return new Promise(resolve => {
            channel.members.map(async (member) => {
                await client.db.get(`SELECT * FROM players WHERE user_id='${member.id}'`, (err, player) => {
                    if (player) {
                        players.push(`[**${player.level}**] ${member} ${player.kills ? `${kills} **${player.kills}** ` : ''}${player.damage ? `${damage} **${player.damage}**` : ''}`)
                    } else {
                        players.push(`[**-**] ${member}`)
                    }
                })
            })
            resolve(players)
        })
  • Вопрос задан
  • 54 просмотра
Решения вопроса 2
@RokeAlvo
как минимум вот это в корне не верно
channel.members.map(async (member) => {})

тут не верное использование map как forEach - но это полбеды...
как вы ожидаете: внутри map делаете асинхронный запрос к базе, получаете player, кладете его в массив. После обработки все массива вызываете resolve(players)
что происходит: map пробегает по members, для каждого стартует промис с запросом, выполняется resolve() - отдает пустой массив, т.к. ни один из промисов еще не разрешился
Замените map на for ... of
Ответ написан
gscraft
@gscraft
Программист, философ
У Вас в коде ворох неразберихи. Во-первых, дело не в запросе. А проверить запрос очень просто: логгируйте результат запроса в теле замыкания, где получаете player (можно заодно посмотреть, что хранится в members). Во-вторых, почему не выбрать сразу всех одним запросом? Запросы в цикле — моветон и лишние расходы. Предполагается
const playerIds = channel.members.map(member => member.id);
// Тут лучше использовать подстановку значений, см. документацию клиента базы данных
const sql = `SELECT * FROM players WHERE user_id IN (${playerIds.join(',')})`;
db.all(sql, (err, players) => resolve(
  players.map(player => `[**${player.level}**] ... ваша строка с пользователем ...`)
));

В-третьих, players нужно определить внутри обещания, в теле Promise. В-четвертых, где и как Вы смотрите результат? Что и как получает ответ от return new Promise? Я полагаю, что у Вас это выглядит примерно так:
function getPlayers() {
  // ...
  return new Promise(resolve => {
     // ...
     resolve(players);
  });
}

getPlayers().then(players => console.log(players));
// или, если getPlayers() объявлено как async
let players = await getPlayers();

— то есть, Вы действительно получаете список игроков как результат Promise?
Ответ написан
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы