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

如何解决Discord.js中await messages引发的未处理Promise拒绝及TypeError问题

问题分析与解决方案

先帮你拆解下触发错误的核心原因,再给出针对性的修复方案:

1. 核心错误根源

(1)awaitMessages 参数顺序完全错误

Discord.js 里 MessageChannel.awaitMessages() 的第一个参数必须是过滤函数(用来筛选要收集的消息),第二个参数才是配置选项(比如max、time)。你直接把配置对象当成第一个参数传入,导致内部代码试图把这个对象当作函数调用apply,这就触发了TypeError: Function.prototype.apply was called on #<Object>这个致命错误。

(2)循环内异步逻辑混乱

  • 用var x会导致所有异步回调共享同一个变量值,引发迭代逻辑错误;
  • message.author.send()是异步操作,你在它的then回调里才赋值dmCh,但紧接着就调用dmCh.awaitMessages()——这时候dmCh大概率还没被赋值,进一步加剧了错误;
  • 循环会一次性触发所有消息发送和收集器,多个收集器同时运行不仅逻辑混乱,还会引发未处理的Promise拒绝警告。

2. 修复后的完整代码

我们用async/await理顺异步逻辑,修正参数顺序,同时解决作用域问题:

// 把这段代码放在一个async函数内部(比如你的命令执行函数里)
async function startQuestionnaire(message, questions) {
  try {
    const answers = [];
    // 先建立私信频道,确保后续操作都有合法的频道对象
    const dmChannel = await message.author.send({
      embed: {
        title: "问卷启动",
        description: "请诚实回答以下问题,涉及个人信息请提供真实内容,每题有1分钟作答时间",
        color: 0xe556f5
      }
    }).then(msg => msg.channel)
    .catch(err => {
      throw new Error("无法给你发送私信,请检查你的私信设置是否开启");
    });

    // 逐个处理问题,确保上一个问题完成后再发下一个
    for (let x = 0; x < questions.length; x++) {
      // 发送当前问题
      await dmChannel.send({
        embed: {
          title: `***Q${x + 1}. ${questions[x]}***`,
          footer: { text: "你有1分钟时间回答!" },
          color: 0xe556f5
        }
      });

      // 等待用户回答:第一个参数是过滤函数,只收集当前用户的消息
      const collected = await dmChannel.awaitMessages(
        msg => msg.author.id === message.author.id,
        { max: 1, time: 60000, errors: ["time"] }
      );

      // 提取并保存回答
      const userAnswer = collected.first().content.toLowerCase();
      answers.push(userAnswer);
      console.log(`收到第${x+1}题回答:${userAnswer}`);
    }

    // 问卷完成后的收尾
    await dmChannel.send({
      embed: {
        title: "问卷完成!",
        description: "感谢你的配合与诚实回答",
        color: 0x43b581
      }
    });
    console.log("所有回答汇总:", answers);
  } catch (err) {
    // 统一处理所有错误(超时、发送失败等)
    if (err.message.includes("time")) {
      await message.author.send("回答超时,问卷已终止");
    } else {
      await message.author.send(`发生错误:${err.message}`);
    }
    console.error("问卷流程错误:", err);
  }
}

3. 关键改动说明

  • 用async/await替代.then()链式调用:让异步逻辑更直观,避免回调地狱,同时方便统一捕获所有错误;
  • 修正awaitMessages参数:第一个参数传入过滤函数,确保只收集当前用户的消息,第二个参数传入配置选项;
  • 使用let x替代var x:确保每次循环迭代都有独立的变量作用域,避免迭代值混乱;
  • 统一错误处理:用外层try/catch捕获所有异步错误,包括发送失败、回答超时等,彻底消除未处理的Promise拒绝警告;
  • 串行处理问题:确保上一个问题回答完成后再发送下一个,逻辑清晰,不会出现多个收集器同时运行的冲突。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.30 08:17:39