Discord.js机器人启动时如何缓存全部服务器成员以直接使用用户ID
解决方案
你现有代码的核心问题是逻辑冗余:你前面已经实现了通过client.users.fetch()主动拉取用户信息的逻辑(这个API不需要本地有缓存,直接调用Discord官方接口拉取用户数据),但后续给embed赋值的时候却没有使用这个提前拉取好的结果,反而又写了一套从本地缓存members.cache取数据的逻辑,才导致必须先ping用户把数据缓存到本地才能通过ID查询。
优化后的代码
module.exports = { config, run: async (client, message, args) => { let embed = new Discord.MessageEmbed(); let mention = message.mentions.members.first() // 优先通过输入的ID直接拉取用户信息,不走本地缓存 if(!mention && !isNaN(args[0]) && args[0]) { try { mention = await client.users.fetch(args[0]) } catch (err) { return message.reply("未找到对应ID的用户,请检查输入是否正确") } } // 匹配用户名查询 if(!mention && args[0] && isNaN(args[0])) { try { const members = await message.guild.members.fetch({query: args[0], limit: 1}) mention = members.first() } catch (err) { return message.reply("未找到对应用户名的用户,请检查输入是否正确") } } // 没有参数默认取消息发送者本人 if(!mention) mention = message.author // 统一处理为User对象 if(mention.roles) mention = mention.user // 直接使用处理好的mention对象,不需要再重复查缓存 embed.setTitle('Avatar!'); embed.setAuthor(message.author.tag, message.author.displayAvatarURL()); embed.setColor(client.config.colors.info); embed.setImage(mention.displayAvatarURL({dynamic: true})); return message.reply({embeds: [embed] }); } }
主要修改点
- 移除了原代码末尾重复的
user变量声明逻辑,直接复用前面已经通过接口拉取到的用户数据,不再依赖本地缓存,只要输入的用户ID合法,不需要提前ping就能直接查询到对应头像 - 给各个fetch分支补充了错误捕获后的提示,用户输入非法ID/用户名时会收到明确反馈,不会出现命令无响应的情况
- 统一了用户对象的处理逻辑,避免出现分支返回的对象类型不一致导致的属性读取错误
内容的提问来源于stack exchange,提问作者Misty
相关产品推荐
相关产品推荐

