0

我正在尝试创建一个 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 运行模拟?

4

2 回答 2

1

您不能像您尝试那样在循环中调用 setTimeout 的原因是因为您正在非常快速(并且递归地)创建数千个计时器,所有这些计时器都需要在堆栈中结束。如果要使用 setTimeout,只需将其放在step_world函数外部而不是内部。

像这样的东西应该工作。它将每 1000/30 毫秒调用一次 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/这样的单元测试框架手动执行此操作。

于 2012-05-06T18:12:03.973 回答
0

我阅读了对另一个答案的评论,但我相信您最初的想法是正确的。问题是您在 setTimeout 调用中立即调用该函数,从而导致无限递归。

发生这种情况是因为您像这样调用 step_world:

step_world(world, step)

每次调用 setTimeout。试试这个

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

它使用参数 world 调用 step_world 并在交易之后执行 step。实现相同结果的另一种方法:

setTimeout(function() {
    step_world(world, step);
}, 1000/30);
于 2012-05-06T23:42:46.217 回答