 
                        app.get("/loginForm?**",function(req,res){
        pool.getConnection(function(err,connection){
        if (err) {
            console.log(err+"--from connection");
            res.send("登录失败,数据库连接错误");
        } else{
            connection.query("USE userInfo",function(err,rows){
                if (err) {
                    console.log(err+"--from using database");
                    res.send("登录失败,数据库使用错误");
                }
            else{
                    var selectQuery = "SELECT * FROM users WHERE userName="+"'"+req.query.username+"'";
                    connection.query(selectQuery,function(err,rows){
                        if (err) {
                            console.log(err+"--from query");
                            res.send("登录失败,数据库查询错误");
                        } else{
                                    if (rows.length==0) {
                                        res.send("登录失败,用户不存在");
                                    } else{
                                        if (req.query.password==rows[0].password) {
                                            res.cookie("username",req.query.username,{
                                                expires: new Date(Date.now() + 900000),
                                                httpOnly:true
                                            });/*res.cookie end*/
                                            res.send("登录成功");
                                        } else{
                                            res.send("登录失败,密码不正确");
                                        }
                                    }
                        }
                    });
                }
            });
        }
        if(connection){connection.release()};
    });
});
回调嵌套太多层导致很难维护了
 //先promise化pool.getConnection
    var getConn = new Promise(function(resolve,reject){
        pool.getConnection(function(err,connection){
            if (err) {
                reject(err);
            } else {
                resolve(connection);
            }
        });
    });
    
   const test = async()=>{
        let connection = await getConn;
        console.log(connection);
    };
    
    这段直接运行会说async undefined
于是我把它babel一下
var _this = this;
var test = function test() {
        var connection;
        return regeneratorRuntime.async(function test$(context$1$0) {
                while (1) switch (context$1$0.prev = context$1$0.next) {
                        case 0:
                                context$1$0.next = 2;
                                return regeneratorRuntime.awrap(getConn);
                        case 2:
                                connection = context$1$0.sent;
                                console.log(connection);
                        case 4:
                        case "end":
                                return context$1$0.stop();
                }
        }, null, _this);
};
运行test()后报错,说regeneratorRuntime undefined,我用的node5.6,不知道问题出在哪里
原来是因为babel依赖一个babel-polyfill的模块,require一下就好了。。。 但是新的问题又来了,pool.getConnction很容易就promise化了,但是connection.query由于依赖前者传回的connection,所以必须在async函数内部promise化才能使用。。。这就蛋疼了
const test = async()=>{
        let connection = await getConn;
        var conn = new Promise(function(resolve,reject){
            connection.query("USE userInfo",function(err,rows){
                if (err) {
                    reject(err);
                } else {
                    resolve(rows);
                }
            });
        });
        let rows = await conn;
        console.log(rows);
    };
    所以就变成这个造型了。。。。有什么办法能把connection.query在外部进行promise化么?
次最终方案出来了,如下
app.get("/loginForm?**", async (req, res) => {
        try {
            let connection = await getConn;
            //promise化connection.query
            var conn = function(queryString) {
                var connPromise = new Promise(function(resolve, reject) {
                    connection.query(queryString, function(err, rows) {
                        if (err) {
                            reject(err);
                        } else {
                            resolve(rows);
                        }
                    });
                });
                return connPromise;
            };
            await conn("USE userInfo");
            let selectQuery = "SELECT * FROM users WHERE userName=" + "'" + req.query.username + "'";
            let rows = await conn(selectQuery);
            if (rows.length === 0) throw '登录失败,用户不存在';
            if (req.query.password !== rows[0].password) throw '登录失败,密码不正确';
            res.cookie('username', req.query.username, {
                expires: new Date(Date.now() + 15 * 60 * 1000),
                httpOnly: true
            });
            res.send("登录成功");
            connection.release();
        } catch (e) { res.send(e); }
    });
    将其babel之后运行成功,为什么是次最终,主要是因为connection.query的promise化写在了主函数里面,显得代码很丑,希望能找到最终方案,让我通关回调地狱QAQ
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号
async/await只对 Promise 对象才有效。首先你要把数据库部分的各个方法改成 Promise 形式的。然后主函数就很简单了:别忘了这里的
pool.getConnection()、connection.query()都要 Promise 化。reject(err)会被catch(e)捕捉到,各种错误说明也是写在调用方法中的。对了,不管怎么样,原文哪种
if(err)-else都是不需要的。对于这种有错就终止/返回函数的情况,只需要判断错误,不需要else。一楼已经给出了终极答案,我也只是用过co库,还没有怎么尝试await/async语法。
不知道楼主有没有理解一楼的代码,如果没有理解,可以先尝试完全Promise 化,之后理解Generator函数, 然后理解一下co库的基本原理,按照这个线路再去使用await/async 语法之后,应该会易懂很多吧。
另外,你说的async包 我用过,不过这东西在await/async语法面前还是太啰嗦了。await/async才是解决nodejs异步问题的终极方案。
还有,else多了,确实很恶心。建议函数尽早返回