自制口袋妖怪_承诺和口袋妖怪-我如何学会异步思考

自制口袋妖怪

by Kalalau Cantrell

通过Kalalau Cantrell

承诺和口袋妖怪-我如何学会异步思考 (Promises and Pokemon — how I learned to think in async)

If you’ve been learning JavaScript, you may have heard about promises and how awesome they are.

如果您一直在学习JavaScript,那么您可能已经听说过诺言以及它们的强大程度。

So, you decided to research the basics. Perhaps you came across the MDN docs on promises or great articles like this one by Eric Elliott or this one by Brandon Morelli. If you’ve read all of these and more, you’ve probably seen the go-to example of promises in action.

因此,您决定研究基础知识。 也许你遇到了诺言MDN文档或像很大的文章这一个由埃里克·埃利奥特或这一个由布兰登莫雷利。 如果您已经阅读了所有这些以及更多内容,那么您可能已经看到了兑现承诺的首选示例。

Once you’ve seen enough of these types of examples, however, you begin to wonder if you’re actually grasping promises. At this point, if you’re like me, you understand conceptually what makes them awesome — they allow you to write asynchronous code in a synchronous pattern — but you’re itching to see an example of what they can do other than sequence a series of console.log that fire at different times.

但是,一旦您已经足够了解这些类型的示例,您就会开始怀疑您是否真正掌握了诺言。 在这一点上,如果您像我一样,则从概念上了解使它们变得很棒的原因-它们允许您以同步模式编写异步代码-但您渴望看到一个示例,说明除了序列化序列外它们还可以做什么在不同时间触发的console.log

So, what did I do? I built a simple Pokemon game, featuring a turn-based battle against an Electabuzz.

那么,我做了什么? 我构建了一个简单的Pokemon游戏,其中包含与Electabuzz的回合制战斗。

This article assumes you understand the promises example referenced above. Please check out the resources linked in the intro paragraph if you need a refresher.

本文假定您了解上面引用的promises示例。 如果需要复习,请检查介绍部分中链接的资源。

基本功能 (Basic functionality)

The Electabuzz and the player each start off with a certain amount of hit points (HP). The first thing that happens is Electabuzz attacks and the player loses some HP. Then, the game waits until the player chooses an attack to use against Electabuzz.

Electabuzz和播放器均以一定的生命值(HP)开始。 发生的第一件事是Electabuzz攻击,玩家失去了一些HP。 然后,游戏等待,直到玩家选择对Electabuzz的攻击。

Yep, the game just waits…and waits…this is the part where I really started appreciating the value of using promises. Once the player chooses an attack, Electabuzz loses some HP and then it attacks again. This loop continues until either Electabuzz’s HP or the player’s HP reaches zero.

是的,游戏只是等待……然后等待……这是我真正开始意识到使用诺言的价值的部分。 玩家选择攻击后,Electabuzz会失去一些HP,然后再次攻击。 这个循环一直持续到Electabuzz的HP或玩家的HP达到零为止。

伪代码 (The Pseudo-Code)

Pretty simple so far. Now, let’s tweak this a bit so that Electabuzz attacks with a more natural timing. I wanted it to seem like he was “thinking” about his move before making it.

到目前为止非常简单。 现在,让我们对其进行一些调整,以使Electabuzz攻击具有更自然的时机。 我希望它看起来像他在做出决定之前就在“思考”他的举动。

While we’re at it, let’s sprinkle in a little bit of promise action so that we can chain on functions that will fire once Electabuzz is done attacking and not a millisecond earlier. This is a turn-based game after all.

在进行此操作时,让我们花一些许诺动作,以便我们可以链接在Electabuzz完成攻击后(而不是一毫秒之前)触发的功能。 毕竟这是回合制游戏。

Great, this setup will later allow us to do this.

太好了,此设置稍后将允许我们执行此操作。

Now, on to the code for the player.

现在,进入播放器的代码。

How do we write a function that when called will wait for user input before finishing its execution? We know it needs to involve an event listener somehow for the user input part. We also know that we should be able to use promises somehow for the asynchronous part…but how to put the two together?

我们如何编写一个函数,该函数在被调用时将在完成执行之前等待用户输入? 我们知道它需要以某种方式让用户输入部分包含事件侦听器。 我们也知道我们应该能够在异步部分使用promise ,但是如何将两者结合在一起呢?

What I found is that if you 1) create a promise, and 2) within that promise add an event listener to, in our case, the click event of a button, and 3) if the function that gets called by the event listener resolves the promise, you can achieve this waiting effect.

我发现的是,如果您1)创建一个Promise,并且2)在该Promise中,向按钮的click事件添加一个事件侦听器,并且3)如果该事件侦听器调用的函数解析诺言,您可以实现这种等待效果。

Voila! Now we’re able to do this.

瞧! 现在我们可以做到这一点。

Note that each call to playerTurn() in the code above will just wait…and wait…until the player chooses to attack. Only then will the execution continue to Electabuzz’s turn and then back.

请注意,上面代码中对playerTurn()每次调用只会等待……然后等待……直到玩家选择攻击。 只有这样,执行才会继续到Electabuzz的回合,然后再返回。

But why write it like that when the same code can be written in its equivalent async/await form, which looks so much nicer? If you’ve been able to follow what we’ve done with promises up to this point, it’s not too much of a leap to see how async/await works. Compare the below code with the above and you’ll see that they are equivalent but the below code is easier to reason around.

但是,当可以用等效的异步/等待形式编写相同的代码时,为什么看起来像这样好看呢? 如果到目前为止,您已经能够遵循我们对诺言所做的一切,那么了解异步/等待的工作方式就不会有太大的飞跃。 将下面的代码与上面的代码进行比较,您会发现它们是等效的,但是下面的代码更容易推理。

Take a deeper dive into async/await by checking out this article by Tiago Lopes Ferreira or these slides by Wes Bos.

请阅读Tiago Lopes Ferreira的这篇文章或Wes Bos的幻灯片 ,以更深入地了解异步/等待。

So, now our code is able to fire off a few rounds of turn-based combat with Electabuzz. But we need a way for the game to end.

因此,现在我们的代码可以使用Electabuzz触发几轮回合制战斗了。 但是我们需要一种结束游戏的方式。

Finally, we’d like the game to continue to run on its own until the game-ending conditions are met. Instead of manually repeating the cpuTurn() and playerTurn() logic like we’ve been doing, we can recursively call our gameLoop() function.

最后,我们希望游戏能够继续独立运行,直到满足游戏结束条件为止。 与其像我们一直在手动重复cpuTurn()playerTurn()逻辑,我们可以递归调用gameLoop()函数。

Now, the gameLoop will run and continue to call itself and continue running until either Electabuzz takes our HP to zero or we take his to zero. If you want want to learn more about recursion, watch this YouTube video by MPJ. While you’re at it, check out the other videos on MPJ’s Fun Fun Function channel. He is great at explaining complex topics in a fun way.

现在, gameLoop将运行并继续调用自身并继续运行,直到Electabuzz将我们的HP设为零或将他的HP设为零。 如果您想了解有关递归的更多信息,请观看MPJ的YouTube视频 。 观看时,请在MPJ的Fun Fun Function频道上观看其他视频。 他擅长以有趣的方式解释复杂的主题。

Let’s take a look at the pseudo-code in full:

让我们看一看完整的伪代码:

代码 (The Code)

Now that we’re through the pseudo-code, here is a Pen showing how I implemented this logic with actual JavaScript:

现在我们遍历了伪代码,这是一支钢笔,显示了我如何使用实际JavaScript实现此逻辑:

结论 (Conclusion)

Thanks for reading. This little experiment with promises showed me that there’s a lot that promises simplify when it comes to composing asynchronous code. Although the typical promises example with console.logs and setTimeouts illustrated the concept, it just didn’t excite me so I decided to create this simple game to get me pumped about promises. I hope you picked up some of that excitement. If there are any async experts out there reading this, it’d be great to hear from you on better ways to achieve the same functionality (with generators, for instance). If anything was unclear to anyone, let me know and I’ll try to clarify.

谢谢阅读。 这个关于promise的小实验告诉我,在编写异步代码时,有很多promise可以简化。 尽管使用console.logs和setTimeouts的典型的Promise示例说明了这一概念,但它并没有让我感到兴奋,因此我决定创建一个简单的游戏来吸引我。 我希望你能从中得到一些兴奋。 如果有异步专家在读这篇文章,那么很高兴听到您提供更好的方法来实现相同的功能(例如,使用生成器)。 如果有人不清楚,请告诉我,我会尽力澄清。

Please feel free to say hello on Twitter.

请随时在Twitter上打个招呼。

翻译自: https://www.freecodecamp.org/news/promises-and-pokemon-how-i-learned-to-think-in-async-2ec098c2c90d/

自制口袋妖怪

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值