-1

I am using https://github.com/gpittarelli/node-ssq to query of a bunch of TF2 game servers to find out if they are on, and if so, how many players are inside. Once I find a server that is on and has less than 6 players in it, I want to use that server's Database ID to insert into somewhere else.

Code looks like this:

for (var i = 0;i < servers.length;i++) {

                ssq.info(""+servers[i].ip, servers[i].port, function (err, data) {

                    serverData = deepCopy(data);
                    serverError = deepCopy(err);
                });

                if (!serverError) {

                    if (serverData.numplayers < 6){
                        //its ok
                        currentServer = servers[i].id;
                        i = 99999;
                    }
                }
                else {
                    if (i == servers.length-1){
                        currentServer = 666;
                    }
                }

            }

And then right after I insert into database with https://github.com/felixge/node-mysql . If I put a console.log(serverData) in there, the info will show up in the console AFTER it inserted into the DB and did a couple other stuff.

So how do I "stop" node, or should I be looking at this / doing this differently?

4

2 回答 2

3

更新:

一个简单的解决方案是将您的if语句移动到回调函数中:

for (var i = 0;i < servers.length;i++) {
  ssq.info(""+servers[i].ip, servers[i].port, function (err, data) {

      serverData = deepCopy(data);
      serverError = deepCopy(err);

      // moving inside the function, so we have access to defined serverData and serverError
      if (!serverError) {

          if (serverData.numplayers < 6){
              //its ok
              currentServer = servers[i].id;
              i = 99999;
              /* add an additional function here, if necessary */
          }
      }
      else {
          if (i == servers.length-1){
              currentServer = 666;
              /* add an additional function here, if necessary */
          }
      }
  });
  // serverData and serverError are undefined outside of the function
  // because node executes these lines without waiting to see if ``ssq.info`` 
  // has finished. 
}

回调中的任何其他函数ssq.info都可以访问该函数中定义的变量。嵌套太多匿名函数时要小心。

原始(nodesque)答案 如果ssq.info是一个异步函数(看起来是这样),Node 将立即执行它并继续前进,仅在ssq.info完成后处理回调函数(您作为最后一个参数传递)。这就是为什么您的console.log语句将立即执行的原因。这是节点异步性质的美丽/恐怖:)

您可以使用setTimeout让 Node 等待,但这会阻碍服务器上的所有其他进程。

在我看来,更好的解决方案是利用 Node 的Event Emiters来:

  1. 监视事件(在这种情况下,当玩家离开服务器时)
  2. 检查玩家人数是否小于6
  3. 如果是这样,请执行您的查询函数(使用回调)

一个很好的入门知识是: Mixu 的 Node Book - Control Flow。另外,请参阅SO 帖子。

于 2013-03-19T16:58:21.817 回答
0

你应该使用回调,

connection.query('INSERT INTO table', function(err, rows, fields) {
  if (err) throw err;
     //entry should be inserted here.

});

http://www.sequelizejs.com/库也更成熟一些,它可能是 node-mysql 的实现问题

于 2013-03-19T16:49:12.677 回答