在Javascript中是睡眠、循环还是什么?

在Javascript中是睡眠、循环还是什么?,javascript,Javascript,我有一个游戏循环,基本上是这样的:function game(){init();setInterval(draw,30);}但是当一个玩家赢了,我想调用Win(),它会清除间隔并重新启动。用javascript解决这个问题的最佳方法是什么?由于setInterval()是异步的,所以我已经退出了game()。所以我要添加一个繁忙的循环:函数game(){while(1){init();setInterval(draw,30);while(!Win);}}?没有什么好方法可以sleep()目前有吗

我有一个游戏循环,基本上是这样的:
function game(){init();setInterval(draw,30);}
但是当一个玩家赢了,我想调用
Win()
,它会清除间隔并重新启动。用javascript解决这个问题的最佳方法是什么?由于
setInterval()
是异步的,所以我已经退出了
game()
。所以我要添加一个繁忙的循环:
函数game(){while(1){init();setInterval(draw,30);while(!Win);}}
?没有什么好方法可以
sleep()
目前有吗?有没有一种方法可以在
Win()
内部调用
game()
,而无需生成任意大小的调用堆栈?处理这种情况的最佳方法是什么?

您可以使用命名间隔:

var time;
function game(){
     init();
     time = setInterval(function (){
          draw();
     }, 30);
}

win(){
    if(time){
        clearInterval(time); // clear the interval
        game(); // start the game again.
    }
}

现在,每当用户获胜并开始游戏时,您必须调用此win函数。

您可以使用命名间隔:

var time;
function game(){
     init();
     time = setInterval(function (){
          draw();
     }, 30);
}

win(){
    if(time){
        clearInterval(time); // clear the interval
        game(); // start the game again.
    }
}

现在,每当用户获胜并开始游戏时,您必须调用此win函数。

您可以将计时器设置为一个变量,例如
var timer=setInterval(…)
,然后通过调用
clearInterval(timer)
清除计时器。然而,在我看来,无论何时使用定时器,你都应该考虑有另一种方法来实现你的目标。你不能从你处理游戏逻辑的任何地方调用<代码> Win()(代码)>?code>draw()看起来像是这个地方,但名字并不意味着你可以使用
delay(毫秒)
@JSelser你说得对,它在draw()中。逻辑很简单,我没有其他的麻烦。在真正的代码游戏中()实际上也被称为init(),但我只是举了一个简单的例子。但是我关于调用堆栈的问题就在这一点上开始了。它不是在增长吗?我能避免吗?@nateyolles我正在Win()中清除,但你的评论并没有真正解决这个问题。在这样一次清除之后,您如何在不增加调用堆栈或忙循环的情况下重新启动?您可以将计时器设置为一个变量,例如
var timer=setInterval(…)
,然后通过调用
clearInterval(timer)
清除计时器。然而,在我看来,无论何时使用定时器,你都应该考虑有另一种方法来实现你的目标。你不能从你处理游戏逻辑的任何地方调用<代码> Win()(代码)>?code>draw()看起来像是这个地方,但名字并不意味着你可以使用
delay(毫秒)
@JSelser你说得对,它在draw()中。逻辑很简单,我没有其他的麻烦。在真正的代码游戏中()实际上也被称为init(),但我只是举了一个简单的例子。但是我关于调用堆栈的问题就在这一点上开始了。它不是在增长吗?我能避免吗?@nateyolles我正在Win()中清除,但你的评论并没有真正解决这个问题。在这样一次清除后,如果不增加调用堆栈或忙于循环,您将如何重新启动?@Black确保您只在适当的时候调用
win
;在draw中保留对
win
的闭包引用,并使用谓词调用
win
。您的堆栈将增加任何
win()
将增加的值,但实际的调用堆栈将在
draw
的底部耗尽,在新的间隔期间,新的调用堆栈将接管。JS游戏引擎或其他轮询循环最初并不容易掌握。但请将其视为绘图底部的隐式睡眠,此时调用堆栈消失,浏览器获取用于渲染/IO工作的线程,然后给您一个新堆栈。@Black您的忙循环实际上会锁定线程,因此不会将其返回给浏览器,因此也不会允许您渲染(或输入输入,甚至允许您在某些浏览器中刷新页面)。依赖隐式睡眠和回调。理想情况下,使用
requestAnimationFrame
而不是
setTimeout
| |
setInterval
,但是让堆栈快速耗尽,而不试图保持线程锁定。@Black理论上是的……在这种情况下,您可能有几个帧经过,其中ame应该已经结束了。如果您依赖于
checkReboot
,那么您需要一个全局
shouldReboot
,设置为
true
或者其他设置。更好的解决方案可能是执行
var pid=setInterval(tick,1000/60);函数tick(){var isOver=draw();if(isOver){win(pid);}
而不是每个
间隔
。这是一种错误的想法。调用堆栈存在,直到堆栈上不再有同步调用。
设置(间隔|超时)
,AJAX,承诺。。。async@Black当主机环境决定时(浏览器的选项卡管理器,或托管JS机器的任何东西)它将启动下一个已调度的同步调用堆栈的执行上下文。如果您之前触发了超时,则它将调用在该超时中注册的函数,并将运行直到堆栈耗尽;此时,线程将恢复到主机上的所有browser/server/app container的东西。然后主机将在JS中设置下一个注册堆栈,等等。@Black假设
next
是我的setInterval示例中的函数名(它被取出来并作为引用传递):
game->pid=setInterval(next)…next()->over=draw()==false……next()->over=draw()==false……next()->over=draw()==true-win()->clearInterval(pid);restart()->game()
每一个
……
都是同步调用的耗尽,以及另一个进入
next
@Black的条目的最终重新调度。确保只在适当的时候调用
win
;在draw中保留对
win
的闭包引用,并使用谓词调用
win
。堆栈将无论增加多少,
win()
都会增加它,但实际的调用堆栈是