我正在尝试创建一个nodejs服务器,我正在运行一个简单的x / y世界,客户端可以从中推送/提取数据。如果我只使用box2d或其他东西在客户端进行这样的世界模拟,我会使用调用步进函数的setTimeout函数。当我在nodejs中尝试它时,这不起作用。服务器因“RangeError:超出最大调用堆栈大小”错误而崩溃。
这是我的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运行模拟?
答案 0 :(得分: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(...)
测试Node的另一种方法是向服务器发出请求。您可以使用curl
或使用http://visionmedia.github.com/mocha/等单元测试框架手动执行此操作。
答案 1 :(得分:0)
我读了另一个评论的评论,但我相信你最初的想法是正确的。问题是你在setTimeout调用中立即调用函数导致无限递归。
这是因为你这样调用step_world:
step_world(world, step)
每次调用setTimeout时。试试这个
setTimeout(step_world, 1000/30, world, step)
使用参数world调用step_world,然后使用dealy调用step。另一种实现相同结果的方法:
setTimeout(function() {
step_world(world, step);
}, 1000/30);