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

如何在Discord.js中从异步函数获取SlashCommand选项选择项?

问题

尝试创建名为/test3的Discord.js斜杠命令,命令包含带选择项的input选项,希望从异步函数getArgumentList获取选择项,但当前实现报错。相关代码如下:

tools.js 代码

module.exports = {
    getArgumentList: () => getArgumentList()
}

async function getArgumentList(){
    return [
        {name: '1', value:'One'},
        {name: '2', value:'Two'},
        {name: '3', value:'Three'},
        {name: '4', value:'Four'},
        {name: '5', value:'Five'}
    ]
}

test3.js 命令代码

const { SlashCommandBuilder } = require("discord.js");
const { getArgumentList } = require("../tools.js")

module.exports = {
    data: new SlashCommandBuilder()
            .setName('test3')
            .setDescription('Test command for commands with options.')
            .addStringOption(option =>
                getArgumentList()
                        .then(list => option.setName('input')
                                                .setDescription('The input to echo back.') 
                                                .setChoices(...list) )),           
    async execute(interaction){ 
        console.log('Testing')
    }
}

报错信息

ExpectedValidationError: Expected
    at InstanceValidator.handle 
    ...
    at Module._load (node:internal/modules/cjs/loader:922:12) {
  validator: 's.instance(V)',
  given: Promise { <pending> },
  expected: [Function: SlashCommandStringOption]
}

Node.js v18.13.0

报错原因

addStringOption的回调函数要求返回SlashCommandStringOption实例,但你当前返回的是getArgumentList()执行后的Promise对象,Discord.js无法识别这个Promise类型,因此抛出类型验证错误。

解决方法

情况1:getArgumentList不需要真正异步(示例场景)

如果你的getArgumentList只是模拟异步逻辑,实际无需异步操作,直接改为同步函数即可:

修改 tools.js:

module.exports = {
    getArgumentList: () => getArgumentList()
}

// 去掉async关键字,改为同步函数
function getArgumentList(){
    return [
        {name: '1', value:'One'},
        {name: '2', value:'Two'},
        {name: '3', value:'Three'},
        {name: '4', value:'Four'},
        {name: '5', value:'Five'}
    ]
}

修改 test3.js:

const { SlashCommandBuilder } = require("discord.js");
const { getArgumentList } = require("../tools.js")

module.exports = {
    data: new SlashCommandBuilder()
            .setName('test3')
            .setDescription('Test command for commands with options.')
            .addStringOption(option =>
                option.setName('input')
                    .setDescription('The input to echo back.') 
                    .setChoices(...getArgumentList())), // 直接调用同步函数获取选项
    async execute(interaction){ 
        console.log('Testing')
    }
}

情况2:getArgumentList确实需要异步(如从数据库/API拉取数据)

Discord.js的命令注册阶段是同步的,无法直接在data属性中使用异步操作。此时需要提前在命令加载阶段获取异步数据,再构建命令:

修改 test3.js 为异步加载形式:

const { SlashCommandBuilder } = require("discord.js");
const { getArgumentList } = require("../tools.js")

// 异步构建命令数据
async function buildCommandData() {
    const list = await getArgumentList();
    return new SlashCommandBuilder()
        .setName('test3')
        .setDescription('Test command for commands with options.')
        .addStringOption(option =>
            option.setName('input')
                .setDescription('The input to echo back.') 
                .setChoices(...list));
}

// 导出异步函数,在命令注册时调用
module.exports = async () => {
    const data = await buildCommandData();
    return {
        data,
        async execute(interaction) {
            console.log('Testing');
        }
    };
};

然后修改你的命令注册脚本,异步加载该模块:

// 命令注册文件示例
const fs = require('fs');
const path = require('path');
const { REST, Routes } = require('discord.js');

async function registerCommands() {
    const commands = [];
    const commandsPath = path.join(__dirname, 'commands');
    const commandFiles = fs.readdirSync(commandsPath).filter(file => file.endsWith('.js'));

    for (const file of commandFiles) {
        const filePath = path.join(commandsPath, file);
        const commandModule = require(filePath);
        // 判断模块是否为异步函数,是则先调用获取命令对象
        const command = typeof commandModule === 'function' ? await commandModule() : commandModule;
        commands.push(command.data.toJSON());
    }

    // 后续REST注册逻辑(省略)
}

registerCommands();

内容的提问来源于stack exchange,提问作者GD Clone

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.04 14:55:15