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

如何在MessageComponentCollector中正确获取变量值?async/await相关变量未定义问题排查

问题排查与解决方案:Discord.js组件收集器中approvalChoice始终为undefined的原因及修复

问题原因分析

你的代码里有两个核心问题导致approvalChoice一直处于undefined状态:

  1. 错误地对事件监听器使用await
    collector.on('end')是事件绑定方法,它返回的是收集器实例而非Promise,所以await collector.on('end', ...)完全起不到等待收集器结束的作用。后面的if (await approvalChoice != "approved") return;会在用户还没点击按钮时就立刻执行——此时approvalChoice还没被赋值,自然是undefined。

  2. 对普通变量使用await无意义
    approvalChoice是普通字符串变量,不是异步Promise对象,await approvalChoice不会让代码等待它被赋值,只会直接返回它当前的初始值(undefined)。

修复方案:将收集器逻辑封装为Promise

要正确等待用户的按钮交互并获取选择值,我们可以把收集器逻辑包装成Promise,通过await来等待用户操作完成。以下是修改后的完整代码:

let senderID = interaction.member.user.id;
const filter = i => (i.customId === `approved_${senderID}` || i.customId === `denied_${senderID}`) && i.user.id === senderID;

// 将收集器逻辑封装为Promise
const getApprovalChoice = () => {
  return new Promise((resolve) => {
    const collector = interaction.channel.createMessageComponentCollector({ filter, time: 60000 });

    collector.on('collect', async i => {
      let choice;
      if (i.customId === `approved_${senderID}`) {
        await i.update({ content: 'Operation approved.', components: [] });
        choice = "approved";
      } else if (i.customId === `denied_${senderID}`) {
        await i.update({ content: 'Operation cancelled.', components: [] });
        choice = "denied";
      }
      collector.stop();
      resolve(choice); // 将用户选择传递给Promise
    });

    collector.on('end', (collected) => {
      // 处理超时未交互的情况,返回默认值
      if (!collected.size) resolve(undefined);
    });
  });
};

// 等待用户完成选择
const approvalChoice = await getApprovalChoice();

// 现在可以正常判断选择结果
if (approvalChoice !== "approved") {
  await interaction.deleteReply();
  return;
}

// 若用户选择approved,执行后续处理逻辑
await interaction.editReply({content: "_**Processing...**_"});

关键改动说明

  • 把收集器逻辑放进返回Promise的函数getApprovalChoice中,当用户点击按钮或收集器超时结束时,通过resolve()传递选择结果。
  • 使用await getApprovalChoice()等待用户操作完成,确保approvalChoice能正确拿到用户的选择值(或超时后的undefined)。
  • 移除了原代码中无效的异步等待逻辑,让代码执行顺序更符合预期——先等待用户选择,再判断结果执行后续操作。

这样修改后,你就能正确获取用户的按钮选择,代码也会按照预期流程执行啦。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.28 16:32:48