我大致知道如何使用循环。我使用了简单的方法,并了解了它的工作原理。但是,我有一种情况,我认为循环会很有用,但我不确定如何获得所需的结果。我是自学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)当显示“翻转”卡类型时,我希望代码暂停,本质上是询问作者是否要使用显示的翻转卡。如果是,请停止循环。如果否,请从其停下的位置继续循环,直到翻转所需的数字,或者显示另一种翻转卡类型。
谢谢您的帮助!
答案 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);
}
})
}