Discord.js forEach循环添加Embed字段失败及ID转用户名问题咨询
问题1:Embed未成功添加字段
原因:sqlite3的db.all()是回调式异步方法,JS不会等待回调执行完成,会直接运行后续的interaction.reply代码,此时你的遍历添加字段的逻辑还没执行,Embed是空的就被发送了。
解决方法:将回调方法Promise化,用await等待数据库查询完成后再回复。需要先引入Node内置的util.promisify包装db.all方法。
问题2:用户ID转用户名#0001格式与await报错
原因:await只能在标记为async的函数内部使用,如果你在普通的回调函数里直接用await就会抛出该错误。
在discord.js中与Python的client.fetch_user对应的方法是interaction.client.users.fetch(用户ID),调用后返回用户对象,其.tag属性就是你需要的用户名#0001格式。
修改后完整代码
const { SlashCommandBuilder } = require('@discordjs/builders'); const { MessageEmbed } = require('discord.js') const sqlite = require('sqlite3').verbose(); const { promisify } = require('util'); // 引入promisify工具处理异步回调 module.exports = { data: new SlashCommandBuilder() .setName('rank') .setDescription('Rank all points.'), async execute(interaction) { const rankEmbed = new MessageEmbed() .setColor('#0099ff') .setTitle('Rank Board') let db = new sqlite.Database('./databases/ranktest.db', sqlite.OPEN_READWRITE); // 将db.all包装为返回Promise的异步方法 const dbAll = promisify(db.all).bind(db); let queryall = 'SELECT name, points FROM pointstable ORDER BY points DESC' try { // 等待数据库查询完成再执行后续逻辑 const rows = await dbAll(queryall, []); // 遍历数据添加字段,同时拉取用户信息 for (const row of rows) { const user = await interaction.client.users.fetch(row.name); rankEmbed.addField('\u200b', `${user.tag}: ${row.points}`, true); } // 所有字段添加完成后再发送消息 return interaction.reply({embeds: [ rankEmbed ] }); } catch (err) { console.log('处理出错:', err); return interaction.reply('查询排行榜数据时出现错误'); } } }
内容的提问来源于stack exchange,提问作者Randorile
相关产品推荐
相关产品推荐

