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

Discord.js Bot Sharding中broadcastEval返回对象方法丢失处理问询

discord.js Sharding模式下broadcastEval使用方案

核心结论

不需要手动构造Guild对象,最优方案是将所有涉及discord.js类实例方法调用的逻辑全部放在broadcastEval传入的函数内部执行,仅返回可序列化的纯数据即可。
你看到的返回值为数组是broadcastEval的默认行为:该方法会在所有激活的分片上执行传入函数,返回结果是每个分片的执行结果组成的数组,而你需要的目标Guild仅存在于负责管理对应服务器ID的单个分片上,其他分片执行查询逻辑会返回无效结果。

优化实现(匹配你获取服务器用户昵称的需求)

async function serverLookup(client, { sID, authNm }) {
  // 提前判断当前分片是否持有目标服务器,过滤无效执行
  if (!client.guilds.cache.has(sID)) return null;
  try {
    const svrInfo = await client.guilds.fetch(sID);
    // 直接在分片内部完成成员拉取、昵称读取逻辑
    const allMembers = await svrInfo.members.fetch();
    // 整理为纯对象数组返回,仅保留需要的基础数据字段
    return allMembers.map(member => ({
      userId: member.id,
      userName: member.user.username,
      displayName: member.nickname ?? member.user.username
    }));
  } catch (err) {
    console.error('查询失败:', err);
    return null;
  }
}

// 先计算目标服务器所属的分片ID,仅指定该分片执行逻辑
const targetShard = bot.shard.idsForGuild(serverID);
const execResult = await bot.shard.broadcastEval(serverLookup, {
  context: { sID: serverID, authNm: msgAuthor },
  shard: targetShard
});

// 过滤无效值后拿到最终需要的用户昵称列表
const memberNicknameList = execResult.filter(Boolean)[0];

注意事项

  • 禁止在broadcastEval外部调用discord.js类实例的内置方法,跨分片传递的所有数据都会经过JSON序列化,会丢失类实例的所有挂载方法,手动重构实例成本极高且容易出现缓存不一致问题,完全没有必要性。
  • 调用broadcastEval时指定目标分片,既可以减少不必要的性能开销,也能避免返回结果中出现大量无效的空值,简化后续数据处理逻辑。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.28 07:36:07