在JavaScript中等待包装setTimeout中的所有内容

在JavaScript中等待包装setTimeout中的所有内容

问题描述:

所以,我正在创建一个在线玩视频游戏的机器人(完全合法,有一个服务器用于机器人比赛,不用担心)。代码是用JavaScript编写的,我现在就拿起来,而且我无法告诉机器人做某事,然后等待时间或条件,直到做其他事情。

So, I'm creating a bot to play a video game online (completely legally, there's a server for bot competitions, don't worry). The code is in JavaScript, which I'm just picking up now, and I'm having trouble telling the bot to do something, then wait either by time or by condition until doing something else.

到目前为止,我只是简单地将所有内容包装在巨大的setTimeout命令中,但这非常不优雅。

So far, I'm simply wrapping everything in gigantic setTimeout commands, but this is extremely inelegant.

没有太多代码与post相关,但基本上我已经编写了很多代码,可以执行诸如移动到特定位置,制动,追逐其他玩家等等。大多数使用递归setTimeout命令 - 按某些按钮,重置变量,然后再次启动该功能如果不符合条件。如果我想移动到一个特定的位置然后在我完成时刹车,通常我会把代码放在这样:

There's not too much code that's relevant to post, but essentially I've made up a lot of code that does things like move to a specific location, brake, chase another player, etc. Most work with a recursive setTimeout command - press certain buttons, reset variables, then start the function again if the condition isn't met. If I want to move to a specific location then brake when I finish with that, generally I'd put code likes this:

moveTarget(target);
brake();
[...Execute rest of code...]

但是,JavaScript同时执行这些命令同时显然不能很好地工作。有没有办法制作更像这样的东西(或等同于条件而不是指定的时间):

However, JavaScript executes both of these commands at the same time, which obviously doesn't work very well. Is there a way to make something more like this (Or the equivalent with a condition instead of a specified time):

moveTarget(target);
wait3Seconds();
brake();
[...Execute rest of code...]

无需执行此操作:

moveTarget(target);
setTimeout(function(){
    brake();
    [...Execute rest of code...]
},3000);

鉴于我将拥有多少这样的情况,我的代码最终看起来像一个巨大的混乱嵌套的setTimeouts,这不是很漂亮。有没有更好的办法?我已经在使用JQuery,所以我非常愿意在必要时使用它。

Given how many of these situations I'll have, my code will end up looking like a gigantic mess of nested setTimeouts, which is not very pretty. Is there a better way? I'm already using JQuery, so I'm perfectly willing to use that if necessary.

一点背景......



JavaScript不会像您可能习惯的其他编程语言一样处理并发。相反,JavaScript只有一个主线程,而是有一个队列用于注册,然后按顺序处理事件。

A little background...

JavaScript does not handle concurrency in the same way as other programming languages you may be used to. Instead, JavaScript has only the one main thread, and instead has a queue for registering then handling events in order as they occur.

因此,它非常重要不要做很长时间会阻塞线程的东西(比如Thread.sleep()这样的函数会这样做)。这就是为什么你应该使用setTimeout或setInterval这样的事情。

For this reason, it is very important to not do things that would block the thread for long periods of time (like a function such as Thread.sleep() would do). That is why you instead should use setTimeout or setInterval for things like this.

你总是可以创建一个自定义睡眠函数来编写你请求的样式的代码。这可能是这样的:

You could always create a custom sleep function to write code in the style you are requesting. This might be something like:

function sleep(millis) {
  var startTime = Date.now();
  while (Date.now() < startTime + millis) {}
}

但这将是非常,非常糟糕。这会在此睡眠功能运行时冻结页面。

But this would be VERY, VERY BAD. This would freeze the page while this sleep function is running.

你基本上需要重构你的代码以使其更加多事。你应该编写你的JavaScript代码来使用回调和超时,而不是在同一个块中有大的线性代码块。

You basically need to refactor your code to be more "eventful". Rather than having large, linear chunks of code within the same block, you should write your JavaScript code to use callbacks and timeouts.

所以你展示的最后一个代码块真的是你应该遵循JavaScript的范例:

So the last code block you showed is really the paradigm you should be following with JavaScript:

moveTarget(target);
setTimeout(function(){
  brake();
  [...Execute rest of code...]
},3000);

但是,如果不是,你当然可以清理很多东西。 ...执行其余代码...] ,将其拆分为其他函数并从setTimeout回调中调用它们。当然,在任何编程语言中保持代码块小而简洁是一个很好的经验法则。

However, you can certainly clean things up a LOT, if instead of [...Execute rest of code...], you split that apart into other functions and call them from within your setTimeout callback. Of course, keeping your code blocks small and concise is a good rule of thumb in any programming language.

你也可以有兴趣查看请求动画帧功能