nodejs中的同步mysql查询

时间:2016-03-14 23:30:07

标签: mysql node.js

我对nodejs很陌生,我在理解如何使用mysql连接对象方面遇到了一些困难。

我的问题不在于代码,而在于设计模式。

假设我有一个用户模块

module.exports = function(){
    return{
        id: "",
        load: function(id){
            var sql = 'SELECT * from users where id = '+ DB.escape(id);
            console.log(1);
            DB.query(sql, function (err, rows) {
                this.id = rows[0].id; // not working
                console.log(rows[0].id); // prints the id 4
                console.log(2);
            });
            console.log(3);
        }
    }
}

从模块外部运行下一个代码

var user = require('../modules/user');
var selected_user = user();
console.log("entering users me route");
selected_user.load(4);
console.log("user id is " + selected_user.id); //This does not print the id 4

当我运行代码时,控制台记录1,然后是3,然后是2。 这是由于节点js的异步流程。

但是,如果我正在构建一个网站,并且在将HTML发送到浏览器之前我需要结束查询以填充我的用户对象???

这样做的正确方法是什么?

此外,当我尝试在数据库中收到的id中填充用户的id属性时,它不起作用。

有什么想法吗?

由于

2 个答案:

答案 0 :(得分:3)

有几种方法可以做到这一点。我会选择Promises

假设您有一个异步函数“getUsers”。 它看起来像这样:

function getUsers() {
    longQuery(function(err, result){
        // What to do with result?
    });

您需要重写它才能使用结果。 我们试试吧:

function getUsers() {
    return new Promise(function(resolve, reject) {
        longQuery(function(err, result){
        if(err) reject(err)
        else resolve(result)
        });
    });

现在这个函数返回一个promise。我们如何处理这一承诺?

function handleRequest(req, res) {
    getUsers().then(function(result) {
        // Do stuff with result
        res.send(myProcessedData);
    }).catch(function(err) {console.log(err)};
}

这也可以通过回调来完成,将响应对象作为参数传递给查询函数,以及许多其他方法,但我认为promises是一种非常优雅的方式来处理它。

答案 1 :(得分:0)

this.id = rows[0].id; // not working

上述行无法正常工作,因为您要从回调函数中将其设置为this.id。当您进入回调函数this时,并不意味着主对象中的this

有关此内容的更多讨论:请参阅How to access the correct `this` context inside a callback?

要解决javascript的异步性质,您可以使用promise来表示matanso的答案,也可以将回调函数传递给load方法。因此,当您获得所需的所有数据时,load: function(id)方法将为load: function(id, callbackFunction)并调用回调函数。