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

Discord.js命令部署脚本执行完成后无法终止的问题

问题描述

我基于Discord.js官方指南修改了命令部署脚本,脚本已成功刷新应用(/)命令并输出成功日志,但进程始终无法终止,不清楚原因。

脚本代码如下:

const commands = [];
const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);
const foldersPath = path.join(__dirname, 'commands');
const commandFolders = fs.readdirSync(foldersPath);

for (const folder of commandFolders) {
    // Grab all the command files from the commands directory you created earlier
    const commandsPath = path.join(foldersPath, folder);
    const commandFiles = fs.readdirSync(commandsPath).filter(file => file.endsWith('.js'));
    // Grab the SlashCommandBuilder#toJSON() output of each command's data for deployment
    for (const file of commandFiles) {
        const filePath = path.join(commandsPath, file);
        const command = await import(filePath);
        if ('commandObject' in command && 'execute' in command) {
            commands.push(command.commandObject.commandInfo);
        } else {
            console.warn(`[WARNING] The command at ${filePath} is missing a required "data" or "execute" property.`);
        }
    }
}

// Construct and prepare an instance of the REST module
const rest = new REST().setToken(botToken);

// and deploy your commands!
(async() => {
    try {
        console.log(`Started refreshing ${commands.length} application (/) commands.`);
        // The put method is used to fully refresh all commands in the guild with the current set
        const data = await rest.put(
            Routes.applicationGuildCommands(clientId, guildId),
            { body: commands }
        );

        console.log(`Successfully reloaded ${data.length} application (/) commands.`);
    } catch (error) {
        console.error(error);
    }
})();
问题原因与解决办法

进程无法终止的核心原因是事件循环中存在未清理的异步资源,以下是具体排查和解决方向:

1. 清理命令文件中的异步残留资源

你通过await import(filePath)加载的命令文件里,可能存在未关闭的定时器(如setInterval)、数据库连接、WebSocket连接等。这些资源会占用事件循环,阻止进程自动退出。

  • 逐一检查所有命令文件,确保这类资源在模块加载后没有长期运行,必要时添加关闭逻辑。

2. 手动销毁REST模块的连接池

Discord.js的REST模块默认使用持久连接池,请求完成后连接池可能仍保持活跃,导致进程无法退出。

  • 在部署成功的日志输出后,添加rest.destroy()销毁连接池:
    console.log(`Successfully reloaded ${data.length} application (/) commands.`);
    rest.destroy(); // 添加这行
    

3. 主动终止进程

如果上述方法无效,可以在所有操作完成后主动调用process.exit(0)强制终止进程。同时建议把顶级的异步逻辑都包裹到一个自执行异步函数中,避免顶级await的潜在问题:
修改后的完整代码示例:

(async () => {
    const commands = [];
    const __filename = fileURLToPath(import.meta.url);
    const __dirname = path.dirname(__filename);
    const foldersPath = path.join(__dirname, 'commands');
    const commandFolders = fs.readdirSync(foldersPath);

    for (const folder of commandFolders) {
        const commandsPath = path.join(foldersPath, folder);
        const commandFiles = fs.readdirSync(commandsPath).filter(file => file.endsWith('.js'));
        for (const file of commandFiles) {
            const filePath = path.join(commandsPath, file);
            const command = await import(filePath);
            if ('commandObject' in command && 'execute' in command) {
                commands.push(command.commandObject.commandInfo);
            } else {
                console.warn(`[WARNING] The command at ${filePath} is missing a required "data" or "execute" property.`);
            }
        }
    }

    const rest = new REST().setToken(botToken);
    try {
        console.log(`Started refreshing ${commands.length} application (/) commands.`);
        const data = await rest.put(
            Routes.applicationGuildCommands(clientId, guildId),
            { body: commands }
        );
        console.log(`Successfully reloaded ${data.length} application (/) commands.`);
        rest.destroy();
    } catch (error) {
        console.error(error);
        rest.destroy();
    }

    process.exit(0); // 主动终止进程
})();

4. 排查模块缓存的影响

动态import()会缓存加载的模块,如果模块中存在长期运行的代码,可能导致进程残留。可以尝试在启动脚本时添加--no-cache参数,或者在加载后清理模块缓存(仅在必要时使用)。

内容的提问来源于stack exchange,提问作者Caleb Renfroe

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.19 20:52:06