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

Discord.js递归等待用户输入函数出现极高延迟问题排查求助

问题根因分析
  • 核心延迟原因:discord.js的channel.awaitMessages默认会收集所有符合过滤规则的消息直到超时,你仅配置了60秒超时,没有添加max: 1参数指定收到1条消息就立即返回,导致每次都会等满60秒才返回结果,直接产生极高延迟。
  • 逻辑异常问题1:awaitMessages返回值为消息Collection集合,而非单个消息对象,你直接访问m.content必然得到undefined,永远无法命中cancel判断逻辑。
  • 逻辑异常问题2:awaitMessages函数定义仅接收1个参数,但你实际调用时传入了「询问Embed生成函数」和「校验函数」2个参数,参数完全错位,执行逻辑和设计预期完全不符。
  • 笔误问题:message.guild.channel.cache应为message.guild.channels.cache,makeError中发送Embed的参数写为embed应为复数embeds,递归调用时未传入正确的参数。
修复后完整代码
const Discord = require("discord.js"),
  { MessageEmbed } = Discord,
  ms = require("ms");

module.exports.run = async (client, message) => {
  async function awaitMessages(promptFunc, validateFunc) {
    // 先发送询问提示
    await promptFunc();

    // 配置max:1,收到1条符合条件的消息立即返回
    const collected = await message.channel.awaitMessages({ 
      filter: m => m.author.id === message.author.id, 
      time: 60000,
      max: 1
    });

    // 处理超时无输入情况
    if (collected.size === 0) {
      await message.channel.send("操作超时已取消");
      return null;
    }

    // 取收集到的第一条消息
    const m = collected.first();
    if (m.content === "cancel") {
      await message.channel.send("cancelled");
      return null;
    }

    const output = await validateFunc(m);
    // 校验不通过返回错误函数,发送后重新递归询问
    if (typeof output === "function") {
      await output();
      return await awaitMessages(promptFunc, validateFunc);
    }
    return output;
  }

  function makeWaitArg(argName, description) {
    const embeds = [new MessageEmbed()
      .setTitle(`Giveaway ${argName}`)
      .setDescription(description + " within the next 60 seconds.")
      .setColor("#2F3136")
      .setTimestamp()
      .setFooter("Create A Giveaway! | Type cancel to cancel.", message.author.displayAvatarURL())];

    return () => message.channel.send({ embeds: embeds })
  };

  function makeError(title, desc) {
    const embeds = [
      new MessageEmbed()
        .setTitle(title)
        .setDescription(desc || "")
        .setFooter("type cancel to cancel")
    ];
    return () => message.channel.send({ embeds: embeds })
  }
  
  const channel = await awaitMessages(
    makeWaitArg("Channel", "Please type the channel you want the giveaway to be in."), 
    ({content}) => {
      if (message.guild.channels.cache.has(content)) return content;
      else return makeError("Channel", "That channel doesn't exist. Try Again.");
    }
  );
  if (!channel) return;

  const prize = await awaitMessages(
    makeWaitArg("Prize", "Please send what you would like the giveaway prize to be"), 
    ({ content }) => {
      if (content.length > 256) return makeError("Giveaway Prize Too Long.", "Please ensure the giveaway prize is less than 256 characters. Try again.");
      else return content;
    }
  );
  if (!prize) return;

  const winnerCount = await awaitMessages(
    makeWaitArg("Winner Count", "Please send how many winners you would like the giveaway to have"), 
    ({ content }) => {
      if (isNaN(content)) return makeError("Invalid Winner Count.", "Please provide valid numbers as the winner count. Try again.");
      else if (parseInt(content) > 15) return makeError("You can not have more than 15 winners per giveaway!")
      else return parseInt(content); 
    }
  );
  if (!winnerCount) return;

  const time = await awaitMessages(
    makeWaitArg("Time", "Please send how long you would like the giveaway to last"), 
    ({ content }) => {
      if (!ms(content)) return makeError("Invalid Time.", "Please provide a valid time. Try again.");
      else return ms(content);
    }
  );
  if (!time) return;

  // Start the giveaway
};
修复说明
  • 给awaitMessages添加max: 1配置,收到1条用户消息立即返回,彻底解决等待超时导致的高延迟问题
  • 修正了参数定义和传递逻辑,区分询问函数和校验函数,递归时正确传参
  • 新增超时无输入的处理逻辑,避免无返回值异常
  • 修正了所有语法笔误,调整了执行顺序,先发送提示再等待用户输入
  • 对winnerCount新增了类型转换,直接返回数字类型方便后续逻辑使用

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.24 21:06:01