保存mysql查询对变量的响应以供以后使用

时间:2016-09-18 15:10:22

标签: javascript mysql node.js express

我正在为私人消息系统编写后端API,我遇到了编写我的一个函数的问题。我需要保存对变量的异步调用的响应,以便在所述异步调用之外使用。

在进一步解释之前,我会提供代码:

app.get("/api/users/:UserID/messages/deletemessage/:MessageID", function(req, res){

    var messageID = parseInt(req.params.MessageID);
    var message = null;  

    connection.query("SELECT * FROM Message WHERE MessageID = ?", messageID, function(err, resp){
        if(!err){
            message = resp[0];
        }
    });
    console.log(message);
    //continue using the message variable here to perform more functionality...
});

您可以看到我正在尝试将message变量分配给mysql数据库的select查询的响应。

当该功能运行时,null将被打印到屏幕上。我知道为什么会发生这种情况,这是因为在完成对数据库的查询之前调用了console.log语句。

我的问题是,如何修复此问题以使用数据库查询范围之外的消息变量?

我只尝试了这个,但没有奏效:

app.get("/api/users/:UserID/messages/deletemessage/:MessageID", function(req, res){

    var messageID = parseInt(req.params.MessageID);
    var message = null;  

    connection.query("SELECT * FROM Message WHERE MessageID = ?", messageID, function(err, resp){
        if(!err){
            connection.end(); //try to end the connection so hopefully it assigns
            message = resp[0];
        }
    });
    console.log(message);
    //continue using the message variable here to perform more functionality...
});

1 个答案:

答案 0 :(得分:0)

在Node.js中,您必须将日志语句移动到查询函数中,其中message变量已分配。

Node不会在记录之前等待该查询完成。节点只是将数据从一个地方传送到另一个地方,它并没有真正等待或“锁定”#34;因为它是一种异步语言。

所以绕过它的方法是将一个函数调用到另一个函数中,在另一个函数内调用另一个函数,你可能认为这会变得混乱而且确实如此。它被称为callback hell

有各种各样的方法,许多已成为今天的标准。回调函数变得非常混乱,导致回调地狱,所以只需使用Promise ChainsYield expressions

Yield表达式适用于生成器函数。它们基本上是*之后function的常规函数​​,如下所示:

function* () {
  // generator function
  // you can use the "yield" keyword here
}

请记住,Node.js默认不解释生成器函数。您必须使用co这样的模块来运行它们。

co非常简单易用。只需将生成器函数放在co函数中,它就可以工作。像这样:

var co = require('co');

co(function* () {
  // you can yield here
});

所以你的代码看起来像这样:

var co = require('co');

app.get("/api/users/:UserID/messages/deletemessage/:MessageID", function(req, res){
    co(function* () {
        var messageID = parseInt(req.params.MessageID);

        var resp = yield connection.query("SELECT * FROM Message WHERE MessageID = ?", messageID);
        // NOTE THE YIELD ^

        var message = resp[0];
        console.log(message);
    });
});

关于yield表达式和生成器函数需要考虑的一些事项:

  • co只是Node v4.x及其下的生成器函数解释器,Node v6.x开箱即用地解释了生成器函数,因此您不需要它。
  • 将yield表达式与数据库查询一起使用,您必须将数据库模块替换为支持co的数据库模块,或者将https://www.npmjs.com/package/mysql-promise等承诺替换为任何其他模块,您只能使用如果他们支持承诺或co
  • ,则会产生结果
  • express.js要求您使用co来添加生成器支持,但是另一个名为Koa的Web框架用app.get替换了^Z中的函数。因此,您可以直接在请求函数内部生成。