You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.05 10:00:03