client.on事件触发时如何正确在Enmap中存取所有成员ID
问题原因
代码存在两处核心逻辑错误,直接导致所有成员ID被合并写入单行数据:
- 传入Enmap的键名写法错误:
${Members}会把存储所有成员ID的数组强制转成逗号拼接的长字符串,相当于你只给Enmap传入了1个键,键名就是所有ID拼接出来的整段文本 - Enmap的
ensure方法逻辑是「检查传入的键是否存在,不存在则为该键写入后续指定的默认值」,你只传入了1个键,自然只会生成1行存储记录,完全达不到预期存储效果。
另外补充一个容易踩的坑:Discord.js触发ready事件时,服务器成员缓存默认不完整,直接读取members.cache会缺失大量成员数据,必须主动调用fetch拉取全量成员才能拿到完整ID列表。
修复方案
根据你实际需要的存储效果二选一即可:
方案1:全量成员ID统一存在同一个键下(适合仅需要读取全服成员ID列表的场景)
不要把ID数组转成字符串当键,固定一个专用键存储全量ID列表即可,参考代码:
client.on('ready', async () => { console.log('Started!'); client.user.setPresence({ status: 'dnd', activity: { name: ``, type: "WATCHING" } }); // 拉取服务器最新数据,避免缓存过时 const Guild = await client.guilds.cache.get("951903386557636729").fetch(); // 拉取全量服务器成员,解决缓存不全的问题 const allMembers = await Guild.members.fetch(); const memberIdList = allMembers.map(member => member.id); // 固定键名存储全量ID列表 client.profile.ensure("guild_all_member_ids", { idList: memberIdList }); // 每次启动更新为最新的ID列表 client.profile.set("guild_all_member_ids", memberIdList, "idList"); console.log(memberIdList) });
方案2:每个成员单独存储一行数据(适合需要按成员ID读写独立配置/数据的场景)
遍历所有成员ID,逐个为单个ID创建独立的Enmap存储条目,参考代码:
client.on('ready', async () => { console.log('Started!'); client.user.setPresence({ status: 'dnd', activity: { name: ``, type: "WATCHING" } }); const Guild = await client.guilds.cache.get("951903386557636729").fetch(); const allMembers = await Guild.members.fetch(); const memberIdList = allMembers.map(member => member.id); // 遍历每个成员ID,单独创建存储条目 memberIdList.forEach(memberId => { client.profile.ensure(memberId, { // 可自行扩展每个成员对应的存储字段,比如积分、等级、加入时间等 joinedAt: allMembers.get(memberId).joinedTimestamp, points: 0 }); }); console.log(`已完成${memberIdList.length}个成员的数据初始化`) });
内容的提问来源于stack exchange,提问作者Jeferson Barboza
相关产品推荐
相关产品推荐

