2012-05-06 48 views
0

我正在尝试创建一个nodejs服务器,我正在运行一个简单的x/y世界,客户端可以从中推/拉数据。如果我只在box2d或类似的东西上在客户端做这样的世界模拟,我会使用setTimeout函数来调用step函数。这在我在nodejs中尝试时不起作用。服务器崩溃,出现错误“RangeError:超出最大调用堆栈大小”。nodejs服务器端模拟

这是我的server.js。 world参数是路由器可以操作的世界对象的实例。

var http = require("http"); 

function start(world, router, handlers) { 

function onRequest(request, response) { 
    router(world, handlers, request, response); 

} 

http.createServer(onRequest).listen(8888); 
console.log("ServerStarted. Listens to 8888."); 

step_world(world,0); 
} 

function step_world(world,step) { 
world.update(); 
step++; 
console.log("updating world: " + step); 
step_world(world,step); 
//setTimeout(step_world(world,step),1000/30); 
} 

exports.start = start; 

所以:我如何使用nodejs运行模拟?

回答

1

你不能在你想要做的循环中调用setTimeout的原因是因为你非常快速地(和递归地)创建了数千个定时器,而这些定时器都需要在堆栈上结束。如果你想使用setTimeout,只需将它放在step_world函数之外,而不是放在里面。

这样的事情应该工作。它会每1000/30 ms调用一次step_world函数,而不会导致堆栈溢出。

function step_world(world,step) { 
world.update(); 
step++; 
console.log("updating world: " + step); 
} 

setTimeout(step_world(world,step),1000/30); 
// or setInterval(...) 

另一种测试节点的方法是仅向服务器发送请求。您可以使用curl或使用单元测试框架(如http://visionmedia.github.com/mocha/)手动执行此操作。

+0

setInterval会但我不相信setTimeout会导致多次调用。 –

0

我读了一篇关于其他答案的评论,但我相信你最初的想法是对的。问题在于你在setTimeout调用中立即调用函数,导致无限递归。

这是因为你调用step_world这样的:

step_world(world, step) 

每当你调用的setTimeout。试试这个代替

setTimeout(step_world, 1000/30, world, step) 

它调用step_world与参数世界和步骤后dealy。另一种达到相同结果的方法:

setTimeout(function() { 
    step_world(world, step); 
}, 1000/30);