Discord.js反应收集器不删除反应 如何实现点击不可重复
问题原因
Discord.js 的反应收集器默认统计的是反应添加事件的总触发次数,而非实时统计当前表情的实际存在数量。即使用户取消反应、你在messageReactionRemove事件中手动移除了反应,之前的添加操作已经被收集器计入统计,所以同一用户反复点击同一个表情会持续累加计数,很快触达你设置的max:4阈值触发收集结束。
现有代码的几个错误点
- 没有在过滤规则中排除机器人自身的反应,你主动添加的👎会被算入收集计数
- 反复给client全局绑定
messageReactionAdd、messageReactionRemove事件,每次执行这段逻辑都会新增一次事件监听,长期运行会出现内存泄漏、事件重复触发的问题 - 异步操作没有加
await,反应移除属于Discord接口异步请求,不加等待的话操作还没执行完成,收集器已经完成了计数统计,移除操作不会抵消已经完成的计数
修复方案
优先使用收集器自带的collect和remove事件替代全局client事件监听,过滤规则中增加重复用户判断、排除机器人,所有异步操作加await:
setTimeout(() => { message.channel.send({ embeds: [messageRollWin] }) .then(async function (sentMsg) { await sentMsg.react("👎"); const reactedUsers = new Set(); // 过滤规则优化 const filter = (reaction, user) => { // 排除机器人、非目标表情 if (user.bot || reaction.emoji.name !== '👎') return false; // 同一个用户重复添加直接过滤,同时移除他的重复反应 if (reactedUsers.has(user.id)) { reaction.users.remove(user.id).catch(console.error); return false; } reactedUsers.add(user.id); return true; }; const collector = sentMsg.createReactionCollector({ filter, max: 4, time: 60000, // 建议加上超时时间避免长期占用资源 errors: ['time'] }); collector.on('collect', async (reaction, user) => { console.log('反应添加,当前有效计数:', reaction.count); // 如果需要用户添加后立即移除,这里加await // await reaction.users.remove(user.id); }); collector.on('remove', (reaction, user) => { reactedUsers.delete(user.id); console.log('反应移除,当前有效计数:', reaction.count, '操作用户:', user.username); }); collector.on('end', collected => { sentMsg.channel.send({ embeds: [messageCountDislike] }) }); }) .catch(console.error); }, 5000);
注意事项
你补充的写法await client.on('messageReactionAdd')是错误的,client.on是同步的事件绑定方法,加await没有任何效果。你需要加await的是事件回调内部的异步操作,比如await reaction.users.remove(user.id)这类接口请求操作。
内容的提问来源于stack exchange,提问作者tvlss
相关产品推荐
相关产品推荐

