节点在函数中乱序执行语句

Node executing statements out of sequence within a function

我正在使用 node-mysql 执行查询和 return 结果。根据标准 mysql-node 文档,一旦查询完成传递错误对象或结果对象,就会执行回调函数。假设查询正确执行(确实如此)。我 运行 通过对结果的 for-in 循环并将每一行中的字段分配为一条连续消息,我计划将其发送回调用,以便可以对其进行适当处理。因此,如果用户想要查看梦幻足球选秀中的最后 5 个选秀权,该函数会接收 num 参数(等于 5),然后会看到一条显示有关所有 5 个选秀权交易详细信息的 returned 消息。函数如下:

exports.getSelections = function(num){


 var query = "Select b.Player, b.Team, b.Position, a.Pick, c.Owner FROM Players b, Owners c,(Select * FROM Draft2 WHERE Year=2015 AND Player_ID >0 ORDER BY PICK DESC LIMIT " + num + ") a WHERE b.Player_ID = a.Player_ID AND c.Owner_ID = a.Owner_ID ORDER BY a.Pick DESC";


 var connection = mysql.createConnection(EXTERNAL_DATABASE_URL);
 connection.query(query, function(err, results, fields){
                    if(!err){
                        for( var i in results){
                            msg += "\n" + results[i].Pick + ". " + results[i].Owner + " selected " + results[i].Player + ",  " + results[i].Position + " from " + results[i].Team 
                        }

                    }else{
                        console.log(err);
                            msg = "There was an error processing your request";
                    }
                });      


                    connection.end(function(err){
                        if(err){
                            console.log("there was an error")
                        }else{
                            console.log("close connection");
                        }
                    });




                        console.log("message to be sent: " + msg);
                        return msg;         

};

通过我的控制台输出总是:

要发送的消息:未定义

这是处理的内容:[根据传递给函数并在查询中使用的数字显示销售交易的详细信息]

我在上面的第二行看到查询的结果,如 [msg] 所示,所以我知道查询执行得当。

这是我的问题:

  1. 我能解释一下为什么控制台会在完成实际循环之前执行要发送的消息吗?

  2. 如果我想确保循环在 returning 值之前完成,我该如何处理?

  3. 此外,connection.end 似乎也没有执行。我想我退出功能太早了??

感谢您的帮助。

正如@Pointy 所暗示的,日志在循环完成之前执行,因为数据库操作connection.query异步。您的所有操作都以正确的顺序执行;只是异步操作在它们自己的时间轴上解决,这就是为什么我们有 运行 完成后的回调。

connection.query 回调甚至有机会 运行 之前,您已经记录了 msg 的值。

尝试将 "message to be sent" console.log 移动到 connection.query 操作的回调中:

exports.getSelections = function(num) {
  var query = "Select b.Player, b.Team, b.Position, a.Pick, c.Owner FROM Players b, Owners c,(Select * FROM Draft2 WHERE Year=2015 AND Player_ID >0 ORDER BY PICK DESC LIMIT " + num + ") a WHERE b.Player_ID = a.Player_ID AND c.Owner_ID = a.Owner_ID ORDER BY a.Pick DESC";
  var connection = mysql.createConnection(EXTERNAL_DATABASE_URL);
  connection.query(query, function(err, results, fields) {
    if (!err) {
      for (var i in results) {
        msg += "\n" + results[i].Pick + ". " + results[i].Owner + " selected " + results[i].Player + ", " + results[i].Position + " from " + results[i].Team
      }
    } else {
      console.log(err);
      msg = "There was an error processing your request";
    }

    console.log("message to be sent: " + msg);

  });
  connection.end(function(err) {
    if (err) {
      console.log("there was an error")
    } else {
      console.log("close connection");
    }
  });

  return msg;
};

此外,在与 msg += "..."

连接之前,可能需要确保 msg 的类型为 String