如何让节点等待?或者可能是另一种解决方案

时间:2013-03-19 16:42:50

标签: javascript node.js

我正在使用https://github.com/gpittarelli/node-ssq查询一堆TF2游戏服务器,以确定它们是否已启用,如果是,则内部有多少玩家。 一旦我找到一个服务器并且其中有少于6个玩家,我想使用该服务器的数据库ID插入其他地方。

代码如下所示:

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;
                    }
                }

            }

然后我用https://github.com/felixge/node-mysql插入数据库。 如果我在其中放置了console.log(serverData),信息将在插入数据库后显示在控制台中,并执行其他一些操作。

那么我如何“停止”节点,或者我应该以不同的方式看待这个/做这个?

2 个答案:

答案 0 :(得分: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. 如果是,请执行查询功能(使用回调)
  4. 这方面的一个很好的基础是:Mixu's Node Book - Control Flow。另请参阅this SO帖子。

答案 1 :(得分: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的实现问题