根据用户输入中断或继续循环

时间:2019-05-22 12:24:31

标签: node.js loops discord.js

我大致知道如何使用循环。我使用了简单的方法,并了解了它的工作原理。但是,我有一种情况,我认为循环会很有用,但我不确定如何获得所需的结果。我是自学Java脚本的人,我尝试过尝试其他一些文章,但是我不记得看到有什么对我的情况有所帮助。这很可能是我理解的空白之一。

我想做的事情:这段代码将把顶层卡片从用于TCG的卡片组中取出。每张卡都有一个“类型”。我希望该人向Discord输入一个命令,例如“!flipcard 10”。我想让机器人绕圈将卡片从牌组顶部翻转,直到达到10或将某种卡片类型翻转过来。我正在使用的卡片“类型”是“动作”,“ evo”,“翻转”和“英雄”。我只希望机器人对“翻转”卡类型做出不同的反应。如果用户输入!flipcard,但每次只能执行一次,我已经获得了可以执行此操作的工作代码。最多可以翻动34张左右的卡,但是这种情况发生的可能性小于较低的张数。

我只是按照我想做的代码编写了代码,但是我一直不知道下一步该怎么做。因此,它还不是完全起作用的代码。目前,我确实收到“非法中断声明”错误,因此我无法取得更多进展。

for (i = 0; i < damageToTake; i++) {
cardRemoved = deckAarray.shift()


//Bunch of stuff edited out for Embed mentioned below

    if (cardType == "Flip"){
       message.channel.send(flipEmbed)
       const filter = m => m.author.id === message.author.id
       author.send(`You revealed a Flip card! Do you wish to use it? Please reply with 'yes' or 'no'.`).then((newmsg) => {
       newmsg.channel.awaitMessages(filter, {
       max: 1,
        }).then((collected) => {

            reply = collected.first();

              if (reply.content == 'yes'){
                 console.log("Yes reply.")
                 break;
              } else if (reply.content == 'no'){
                 console.log("No reply")
                 } 
                })
            })
            } else if (cardType != "Flip"){
                message.channel.send(nonflipEmbed)
                continue;
            }
        }
    })
    }

就像我提到的那样,代码无法正常工作,我可以尝试并遇到问题,因为我遇到了“非法中断声明”错误。

我认为我走在正确的轨道上,但是我不确定如何使其完全按照我的期望工作。

所以,总结一下……

我希望将此代码用于以下内容:

1)用户输入命令并指定要翻转的卡数。 2)循环应翻转卡片(根据卡片类型显示正确的嵌入) 3)当显示“翻转”卡类型时,我希望代码暂停,本质上是询问作者是否要使用显示的翻转卡。如果是,请停止循环。如果否,请从其停下的位置继续循环,直到翻转所需的数字,或者显示另一种翻转卡类型。

谢谢您的帮助!

2 个答案:

答案 0 :(得分:0)

您已经更改了上下文-因为您有两个对彼此的控制流一无所知的函数(例如:if / then,for循环,while循环等)。他们无法以您想要的方式互相影响。您正在做的事情等同于以下伪代码:

function printAllNumbers() {
  for(currentNumber : allNumbers) {
    printNumber(currentNumber);
  }
}

function printNumber(num) {
    print(num);
    break; // This won't work because it has no clue about for/loop in other func
}

printNumber的作用域是作用域,因此它仅知道自己的功能(这2行)在做什么。它没有关于printAllNumbers调用中的for / each的任何线索,因此您将看到错误。

而我上面所说的只是部分正确-到目前为止,实际上您可能有2个函数,因为您已调用.then(),然后在.newMessage()之后调用了另一个.then()。您正在按顺序阅读代码,但是您应该尝试以这种方式将其视为分支路径:

for {
    call async functions and (.then) call these other functions
}
...some time passes
<branched off path> The other functions within .then(functions) get called

我建议您阅读异步函数的工作方式,以及promise的工作方式,以更好地理解代码将按什么顺序执行。

要执行所需的操作,您需要编写单独的代码来处理以下情况:

1)从用户那里收到卡的数量,然后进行循环遍历并打印这些卡以进行聊天

2)根据用户(需要跟踪用户)以及已翻转的卡的当前状态接收进一步的输入-可能想对卡编号,并让它们发送诸如USE 1或USE之类的命令全部取消

代码不会在循环的中间暂停以等待输入,它们必须是不同的代码。

答案 1 :(得分:0)

如果没有代码修改,您要尝试执行的操作是不可能的。这样做的原因是for循环是同步的,而promise不是同步的。这意味着.then()仅在循环完成之后才能到达。

一种解决方法是将所有内容包装在异步函数中,然后在其中运行循环。然后,在需要时使用try-catch子句打破循环。考虑下面的玩具示例:

 ( async () => {
    for (i = 0; i < 100; i++) {
        console.log('i:', i);

        try {
            const val = await randomPromise();
            console.log('should resolve and break!');
            console.log(val);
            break;
        } catch (e) {
            console.log('moving on...');
        }
    }
})();


 function randomPromise() {
    return new Promise( (resolve, reject) => {
        const val = Math.random();
        if (val > 0.9) {
            resolve(val);
        } else {
            reject(0);
        }
    })
 }