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

Discord.js按钮触发RPG战斗阶段循环推进问题

Discord RPG机器人战斗系统:解决while循环不等待按钮交互的问题

你的问题出在while循环的执行逻辑和Discord组件收集器的事件驱动模型不兼容:while会快速迭代执行所有循环体代码,虽然你用了await message.channel.send(),但收集器是通过on("collect")事件触发的,循环根本不会等这个事件发生,直接就进入下一次循环,导致一次性发完所有5回合的消息。

解决思路是把按钮交互的等待逻辑封装成Promise,让while循环每次迭代都等待这个Promise完成(也就是用户点击按钮)后,再进入下一轮。

修改后的代码示例

let turn = 1
let phase = 0

// 封装等待按钮点击的Promise函数
async function waitForValidButton(msg, userId) {
  return new Promise((resolve) => {
    const collector = msg.createMessageComponentCollector({
      filter: (interaction) => interaction.user.id === userId,
      time: 60000 // 可选:添加超时时间,防止用户一直不点击
    })

    collector.on("collect", async (btn) => {
      await btn.deferUpdate()
      if (btn.customId === "c") {
        collector.stop()
        resolve() // 用户点击有效按钮,resolve Promise
      }
    })

    // 可选:处理超时情况
    collector.on("end", (_, reason) => {
      if (reason === "time") {
        msg.channel.send("等待超时,战斗结束。")
        resolve("timeout")
      }
    })
  })
}

// 改用异步循环,每次等待按钮点击后再迭代
while (turn <= 5) {
  // 这里写每回合/阶段的游戏逻辑
  const stage_embed = new discord.MessageEmbed()
    .setTitle(`第${turn}回合 - 第${phase+1}阶段`)
    .setDescription("点击按钮进入下一阶段")
    // 你的embed配置...

  const msg = await message.channel.send({ embeds: [stage_embed], components: [row] })
  
  // 等待用户点击按钮
  const result = await waitForValidButton(msg, message.author.id)
  if (result === "timeout") break // 超时则终止循环

  // 更新阶段和回合
  phase += 1
  if (phase > 3) {
    phase = 0
    turn += 1
  }
}

// 战斗结束逻辑
await message.channel.send(`战斗结束!共进行了${turn-1}回合`)

关键改动说明

  • Promise封装交互等待:把收集器的逻辑放进Promise里,只有当用户点击指定按钮时才resolve,让循环必须等待这个动作完成。
  • 异步循环控制:while循环现在会在每次迭代时等待waitForValidButton的Promise完成,彻底解决了一次性发送所有消息的问题。
  • 可选超时处理:添加了超时逻辑,避免用户长时间不操作导致程序卡住。
  • 变量声明优化:把var改成let,符合现代JS规范,避免变量提升问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.16 01:11:07