【问题标题】:Discord.js message collector in a loop for tic tac toe井字游戏循环中的 Discord.js 消息收集器
【发布时间】:2020-11-02 18:35:06
【问题描述】:

所以我开始使用 discord.js 制作一个不和谐机器人,它有一个用于井字游戏的命令。 我尝试在while循环中使用消息收集器,就像这样。进入循环后,什么也没有发生。我添加了一个console.log 来查看totalRouds 变量是否正在修改并且确实如此,因此循环以某种方式传递了消息收集器代码并仅执行最后一行。

while(numberOfrounds < 9){
      const filter = m => m.author.id === message.author.id;
      message.reply('Enter a position:');
      message.channel.awaitMessages(filter, {max: 1, time: 3000, errors: ['time']}).then(collected => {

      // code for drawing a canvas 

      }).catch(err => {
              console.log(err);
      });
      console.log(totalRouds);
      numberOfrounds ++;
}

【问题讨论】:

    标签: discord.js


    【解决方案1】:

    .awaitMessages() 返回一个Promise,它异步解析为您收集的消息数据。这意味着,虽然您的最后一条日志语句在您开始收集消息后立即运行,但收集的消息仅在稍后时间可用并因此处理。

    为了说明这一点,让我稍微整理一下您的代码,并按照您的代码正常运行的顺序添加一些日志:

    while (numberOfrounds < 9) {
        console.log("1");
        const filter = m => m.author.id === message.author.id;
        message.reply('Enter a position:');
        console.log("2");
        message.channel.awaitMessages(
            filter,
            { max: 1, time: 3000, errors: ['time'] }
        ).then(collected => {
            console.log("5, after resolving, the collected data is only now avaiable");
        }).catch(err => {
            console.log(err);
        });
        console.log("3");
        console.log(totalRouds);
        numberOfrounds++;
        console.log("4, immediately starts the next loop, back to #1 again");
    }
    

    我假设您的totalRouds 变量是在传递给.then() 的回调函数中定义的。因此,除了拼写错误(让我们更正一下),您的变量将被定义在错误的范围内,因此 totalRounds 将始终保持未定义,即使在 Promise 使用您收集的消息解析之后,您处理这些消息,您设置 @ 987654330@ 回调函数等。所以这是我们更新的sn-p:

    while (numberOfrounds < 9) {
        const filter = m => m.author.id === message.author.id;
        message.reply('Enter a position:');
    
        message.channel.awaitMessages(
            filter,
            { max: 1, time: 3000, errors: ['time'] }
        ).then(collected => {
            let totalRounds = 1 // Do your processing here
            console.log(totalRounds); // This should log as expected
        }).catch(err => {
            console.log(err);
        });
        numberOfrounds++;
    }
    

    但这可能仍然不是您正在寻找的行为。为什么?您的机器人将尝试一次发送所有 9 个回复(假设您的 numberOfRounds 早从 0 开始),此时 Discord.js 将自动分批发送它们以避免向 API 发送垃圾邮件,并且所有消息收集器将同时等待。您可能打算“暂停”或暂停处理,直到 .awaitMessages() 返回的 Promise 解决并且您已完成处理返回的数据,从而在使用异步方法调用时导致同步行为(因此您说“循环以某种方式通过消息收集器代码并仅执行最后一行”)。为此,我们可以使用async-await

    /*
        You have not provided your full code,
        so what you need to do is mark your message event's
        callback function as async.
        Refer to the linked article on MDN.
    */
    
    while (numberOfrounds < 9) {
        const filter = m => m.author.id === message.author.id;
        message.reply('Enter a position:');
    
        /*
            Then, wait for the Promise returned by
            this promise chain to resolve
            before resuming operation
            and moving on to the next iteration.
        */
        await message.channel.awaitMessages(
            filter,
            { max: 1, time: 3000, errors: ['time'] }
        ).then(collected => {
            let totalRounds = 1 
            console.log(totalRounds);
        }).catch(err => {
            console.log(err);
        });
        numberOfrounds++;
    }
    

    我的术语可能不是 100% 正确,但这是我的理解。如果可以进行改进,请随时发表评论。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-12-30
      • 1970-01-01
      • 2015-07-18
      • 2021-03-31
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多