简体   繁体   English

setTimeout()中的第二个函数未运行

[英]Second function in setTimeout() doesn't run

So I'm new to discord botting and js and I'm playing around with my own bot. 因此,我是不熟悉Botting和JS的新手,并且正在玩自己的机器人。 I want to make a typing minigame. 我想做一个打字迷你游戏。 When you type ?type in chat, the bot will say something in chat and then edit that message while counting down. 当您在聊天中键入?type时,机器人会在聊天中说出一些内容,然后在倒计时时编辑该消息。 When the counting down is finished, it will display the random generated word. 倒计时完成后,它将显示随机生成的单词。 The player needs to type the exact random word in the chat and the bot will show the total time taken. 玩家需要在聊天中输入确切的随机单词,然后漫游器会显示所花费的总时间。

Here is my code: 这是我的代码:

case "type":
        let randomWord = Math.random().toString(36).replace(/[^a-z]+/g, '');
        let timer = 3;
        message.channel.send("Generating a new word..")
          .then((msg)=> {
            var interval = setInterval(function () {
              msg.edit(`Starting in **${timer--}**..`)
            }, 1000)
          });
        setTimeout(function() {
          clearInterval(interval);
          message.channel.send(randomWord)
          .then(() => {
            message.channel.awaitMessages(response => response.content == randomWord, {
              max: 1,
              time: 10000,
              errors: ['time'],
            })
            .then(() => {
              message.channel.send(`Your time was ${(msg.createdTimestamp - message.createdTimestamp) / 1000} seconds.`);
            })
            .catch(() => {
              message.channel.send('There was no collected message that passed the filter within the time limit!');
            });
          });
        }, 5000);
        break;

Currently the code stops after it counted to down 0. I dont understand why message.channel.send(randomWord) doesn't work. 当前代码在计数到0后停止。我不明白为什么message.channel.send(randomWord)不起作用。 Also I would love it if someone could help me change this code to use asynch and await if that's something viable. 如果有人可以帮助我将这段代码更改为使用异步并且如果可行的话,我也很喜欢。

I started researching your problem and here's the system I came up with. 我开始研究您的问题,这是我想出的系统。

Here is the bot listening to messages from different users. 这是机器人在侦听来自不同用户的消息。 Once a user types '?type' , the function runWordGame is called, passing in the message's channel. 用户键入'?type' ,将调用函数runWordGame ,传入消息的通道。

// set message listener 
client.on('message', message => {
    switch(message.content.toUpperCase()) {
        case '?type':
            runWordGame(message.channel);
            break;
    }
});

Here in runWordGame , the bot creates a random word, then displays a countdown to the user (see displayMessageCountdown below). 机器人在runWordGame创建一个随机单词,然后向用户显示倒计时(请参见下面的displayMessageCountdown )。 When the countdown is over, the message is edited with the random word. 倒数计时结束后,将使用随机词编辑消息。 Next, the bot waits for 1 message for 10 seconds - waiting for the user to input the random word. 接下来,机器人等待1条消息10秒钟-等待用户输入随机单词。 If successful, a success message is sent. 如果成功,则发送成功消息。 Otherwise, an error message is sent. 否则,将发送错误消息。

// function runs word game
function runWordGame(channel) {
    // create random string
    let randomWord = Math.random().toString(36).replace(/[^a-z]+/g, '');

    channel.send("Generating a new word..")
    .then(msg => {
        // display countdown with promise function :)
        return displayMessageCountdown(channel);
    })
    .then(countdownMessage => {
        // chain promise - sending message to channel
        return countdownMessage.edit(randomWord);
    })
    .then(randomMsg => {
        // setup collector
        channel.awaitMessages(function(userMsg) {
            // check that user created msg matches randomly generated word :)
            if (userMsg.id !== randomMsg.id && userMsg.content === randomWord)
                return true;
        }, {
            max: 1,
            time: 10000,
            errors: ['time'],
        })
        .then(function(collected) {
            // here, a message passed the filter!
            let successMsg = 'Success!\n';

            // turn collected obj into array
            let collectedArr = Array.from(collected.values());

            // insert time it took user to respond
            for (let msg of collectedArr) {
                let timeDiff = (msg.createdTimestamp - randomMsg.createdTimestamp) / 1000;

                successMsg += `Your time was ${timeDiff} seconds.\n`;
            }

            // send success message to channel
            channel.send(successMsg);
        })
        .catch(function(collected) {
            // here, no messages passed the filter
            channel.send(
                `There were no messages that passed the filter within the time limit!`
            );
        });
    })
    .catch(function(err) {
        console.log(err);
    });
}

This function extrapolates the countdown message display. 此功能外推倒计时消息显示。 The same message object is edited until the timer gets to zero, then the Promise gets resolved, which triggers the next .then(... method inside runWordGame . 编辑相同的消息对象,直到计时器为零,然后解决Promise,这将触发runWordGame的下一个runWordGame .then(...方法。

// Function displays countdown message, then passes Message obj back to caller
function displayMessageCountdown(channel) {
    let timer = 3;

    return new Promise( (resolve, reject) => {
        channel.send("Starting in..")
        .then(function(msg) {
            var interval = setInterval(function () {
                msg.edit(`Starting in **${timer--}**..`);

                // clear timer when it gets to 0
                if (timer === 0) {
                    clearInterval(interval);
                    resolve(msg);
                }
            }, 1000);
        })
        .catch(reject);
    }); 
}

Let me know if you have questions, or if you are looking for a different end result. 如果您有任何疑问,或者正在寻找其他最终结果,请告诉我。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM