井字游戏循环中的Discord.js消息收集器

时间:2020-07-13 14:25:21

标签: discord.js

因此,我开始使用discord.js制作一个discord机器人,该机器人具有一个井字游戏命令。 我尝试在一个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 ++;
}

1 个答案:

答案 0 :(得分: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用收集到的消息解析后,您也可以处理这些消息,您可以在回调函数等中设置totalRounds 之内。因此,这是我们更新的代码段:

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,并且所有消息收集器都将等待同时。您可能打算“暂停”或暂停处理,直到Promise返回的.awaitMessages()解析并且您已经完成对返回数据的处理,从而在使用异步方法调用时引起同步行为(因此,您说“循环以某种方式传递了消息收集器代码并仅执行了最后一行”)。为此,我们可以使用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%正确,但这是我的理解。如果可以改进,请随时发表评论。