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

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

到目前为止,我只是将所有东西都包装在巨大的setTimeout命令中,但这非常不优雅。

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

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

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

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

无需这样做:

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

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

一点背景……

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

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

您始终可以创建自定义睡眠function,以便以您请求的样式编写代码。 这可能是这样的:

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

但这将是非常非常糟糕的 。 这将在此睡眠function运行时冻结页面。

回到你的问题......

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

因此,您展示的最后一个代码块实际上是您应该遵循JavaScript的范例:

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

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


您可能还有兴趣检查请求动画帧function 。

没有更好的方法可以做到这一点。 原因是任何类型的等待都将触发进入任务队列的任务。 由于javascript是单线程的,因此它必须使用这些任务队列,因此如果存在指令,它将继续执行超过setTimeout的指令。

为了在延迟后执行代码,它必须在超时回调中,否则它将立即执行。

如果您在具有wait命令的链中创建了所有方法,则可以执行此操作,类似于jQuery队列系统。

 $("
").queue(function(next){ // do a a(); next(); }).delay(3*1000).queue(function(next){ // after 3 seconds do b b(); next(); }).delay(3*1000).queue(function(next){ // after 3 more seconds do c c(); next(); }).dequeue(); //.dequeue() starts it, only has to be called to make a queue that isn't currently running begin.

所以你要做的就是保持相同的链并不断添加它。