discord.js V14.7.1:Slash命令重复调用致监听器内存泄漏求助
解决Discord.js V14中InteractionCreate监听器内存泄漏问题
你的问题出在每次执行命令时都向client添加了新的InteractionCreate监听器,这些监听器不会自动销毁,积累到一定数量就触发了内存泄漏警告。根本不需要通过新增监听器来实现“重复调用命令停止旧收集器”的逻辑,改用全局存储管理用户的收集器即可。
具体实现步骤
在客户端初始化时添加全局收集器存储
在你的机器人主文件(比如index.js)中,给client挂载一个Map用来跟踪每个用户的活跃图片收集器:// 初始化客户端后添加 client.imageCollectors = new Map(); // key: 用户ID, value: 图片收集器实例修改命令文件的execute函数逻辑
移除原来添加监听器的代码,改为在执行命令时直接检查并管理全局Map中的收集器:// 命令文件中的execute函数 const { SlashCommandBuilder } = require('discord.js'); module.exports = { data: new SlashCommandBuilder() .setName('你的命令名') .setDescription('收集用户发送的图片'), async execute(interaction) { const userId = interaction.user.id; const client = interaction.client; // 检查当前用户是否有活跃收集器,有则停止并清理 const existingCollector = client.imageCollectors.get(userId); if (existingCollector) { existingCollector.stop('用户重复调用命令'); client.imageCollectors.delete(userId); await interaction.reply({ content: '已终止之前的图片收集,现在启动新的收集任务', ephemeral: true }); } else { await interaction.reply({ content: '开始收集你的图片,再次调用命令可终止收集', ephemeral: true }); } // 创建新的图片收集器(根据你的需求调整过滤条件和超时时间) const imageCollector = interaction.channel.createMessageCollector({ filter: msg => msg.author.id === userId && msg.attachments.size > 0, time: 60000 // 1分钟无操作自动停止 }); // 将新收集器存入全局Map client.imageCollectors.set(userId, imageCollector); // 收集器结束时自动清理Map条目 imageCollector.on('end', (collected, reason) => { client.imageCollectors.delete(userId); // 发送结束提示(忽略已过期的交互) interaction.followUp({ content: `图片收集结束,共收到${collected.size}张图片,原因:${reason}`, ephemeral: true }).catch(() => {}); }); // 处理收集到的图片 imageCollector.on('collect', msg => { const attachment = msg.attachments.first(); interaction.followUp({ content: `收到图片:${attachment.url}`, ephemeral: true }).catch(() => {}); }); } };
方案优势
- 彻底避免了重复添加监听器的问题,不会触发内存泄漏警告。
- 全局Map统一管理收集器,确保同一用户同一时间只有一个收集实例运行。
- 收集器结束后自动清理存储,不会残留无效数据占用内存。
内容的提问来源于stack exchange,提问作者idksecret
相关产品推荐
相关产品推荐

