节点js:快速js异步数据库查询执行 - 返回结果得到了undefiend

时间:2017-03-31 09:57:19

标签: javascript node.js express asynchronous

刚开始学习快速js框架,这是我用这个url localhost:3000/api/test调用的简单数据库查询执行部分。

db.query('SELECT * FROM user', function (error, results, fields) {
            if (error) throw error;
            console.log('The result is:', results[0].id);

            return results;
        });

它真的是异步吗?假设另一个用户请求此url是否需要等待先前的查询执行??。

我听说过async包,但不知道这在我的情况下是如何适用的

更新

我在console.log()中得到了正确的结果;但是当我返回结果时我得到了未定义的错误

这是我的model.js

module.exports = {
    getUser:function () {
        db.query('SELECT * FROM user', function (error, results, fields) {
            if (error) throw error;
            console.log('The result is: ', results[0].id);

        });

    }

}

来自我的controller.js

var model = require('../models/user.js');
module.exports = {
    getData : function(req, res){
        //invoke model
        console.log(model.getUser());

    }
}

2 个答案:

答案 0 :(得分:3)

节点是非阻塞的,并且会在调用它时提供此请求。

如果另一个用户点击此端点,那么它将再次执行,无论第一个查询是否已完成(除非SQL已锁定该表,在这种情况下,所有连续的连接/查询将等待并因此而超时)。这种情况发生在连接的基础上。

你应该确保在这里检查你的SQL服务器(MySQL?)配置,以确保有足够的max_connections能够应付你期望的任何负载。

请记住,应用程序的最大瓶颈是usually数据库。

上面的查询需要回调才能异步返回数据。

db.query('SELECT * FROM user', function (error, results, fields) {
    if (error) throw error;
    console.log('The result is:', results[0].id);

    //cb=callback function passed in to context
    if (cb) cb(results);
});

更新了更新回答的答案

在你的model.js中:

module.exports = {
    getUser:function (cb) {
        db.query('SELECT * FROM user', function (error, results, fields) {
            if (error) throw error;
            console.log('The result is: ', results[0].id);
            if (cb) cb(results);

        });

    }

}

在你的controller.js中:

module.exports = {
    getData : function(req, res){
        //invoke model

        model.getUser(function(results) {
            console.log(results);
        });

    }
}

答案 1 :(得分:0)

当你处理回调时,处理它们的安全和干净的方法是Promises。它现在是JavaScript的标准配置,并且不需要任何模块。

是的,它是异步的。在后面,将有网络访问和与数据库服务器的对话。只有当他们完成聊天时才会调用回调。

module.exports = {
    getUser: function () {
        // wrap asynchronously called callback in Promise
        new Promise((resolve, reject) => {
            db.query("SELECT * FROM user", (error, results, fields) => {
                if (error) {
                    reject(error); // similar to "throw"
                }
                else {
                    resolve({ results, fields }); // similar to "return"
                }
            });
        });
    }
};

你如何使用它:

香草符号:

// similar to "try"
model.getUser()
.then((answer) => {
    console.log("answer", answer);
})
// similar to "catch"
.catch((error) => {
    console.log("error", error);
});

async-await表示法(仅在nodejs和浏览器的最新版本中可用):

// you must be in an async environement to use "await"
async function wrapper() {
    try {
        var answer = await model.getUser(); // wait for Promise resolution
        console.log("answer", answer);
    }
    catch(error) {
        console.log("error", error);
    }
}
// async function return automatically a Promise so you can chain them easily
wrapper();