【问题标题】:Node js: Express js asynchronous db query execution-return results got undefiendNode js:Express js异步数据库查询执行-返回结果未定义
【发布时间】:2017-08-25 13:22:26
【问题描述】:

刚开始学习 express 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());

    }
}

【问题讨论】:

标签: javascript node.js express asynchronous


【解决方案1】:

节点是非阻塞的,并且会在它被调用时处理这个请求。

如果另一个用户点击此端点,那么无论第一个查询是否完成,它都会再次执行(除非 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);
        });

    }
}

【讨论】:

  • 所以当另一个请求到来时它会同时处理??
  • 还有一个问题,我需要一个回调函数来处理结果吗??
  • @Jabaa:是的,它是同时的,你不需要做任何回调。
  • 但是当我返回结果时我得到了未定义
  • @Jabaa:您是否尝试过查看是否有任何恢复? console.log(results); 。拨打此电话时数据库连接是否处于活动状态?
【解决方案2】:

当您处理回调时,处理它们的安全和干净的方法是 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();

【讨论】:

    猜你喜欢
    • 2020-06-20
    • 2015-07-15
    • 1970-01-01
    • 1970-01-01
    • 2020-06-01
    • 2014-07-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多