How to rewrite this code with async? How to transfer res, req across layers

  node.js, question
app.get("/loginForm?  **",function(req,res){
 pool.getConnection(function(err,connection){
 if (err) {
 Log (errplus "-fromconnection");
 Res.send ("Login Failed, Database Connection Wrong");
 } else{
 connection.query("USE userInfo",function(err,rows){
 if (err) {
 Log (errplus "-fromusing database");
 Res.send ("Login Failed, Database Used Wrong");
 bracket
 else{
 Var selectquery = "select * fromusers where username =" plus "'"plus req.query.username plus "'";
 connection.query(selectQuery,function(err,rows){
 if (err) {
 Log (errplus "-fromquery");
 Res.send ("Login Failed, Database Query Error");
 } else{
 if (rows.length==0) {
 Res.send ("Login Failed, User Does Not Exist");
 } else{
 if (req.query.password==rows[0].password) {
 res.cookie("username",req.query.username,{
 Now () plus 900000.
 httpOnly:true
 });  /*res.cookie end*/
 Res.send ("successful login");
 } else{
 Res.send ("Login Failed, Password Incorrect");
 bracket
 bracket
 bracket
 });
 bracket
 });
 bracket
 if(connection){connection.release()};
 });
 });
 
 Callbacks are nested too many times, making them difficult to maintain.

According to the answer on the first floor, I did some experiments. The first was the code.

//first promise to pool.getConnection
 var getConn = new Promise(function(resolve,reject){
 pool.getConnection(function(err,connection){
 if (err) {
 reject(err);
 } else {
 resolve(connection);
 bracket
 });
 });
 
 const test = async()=>{
 let connection = await getConn;
 console.log(connection);
 };

This direct run will say async undefined.
So I gave it babel once

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();
 bracket
 }, null, _this);
 };

After running test (), I reported an error, saying that the regeneratorRuntime undefined, node5.6 I used, did not know where the problem was.


It turns out that babel depends on a babel-polyfill module, and require is good. . . However, there is a new problem. pool.getConnction can be easily promoted. However, connection.query relies on the connection returned by the former, so it must be promoted within the async function before it can be used. . . This egg hurts

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);
 bracket
 });
 });
 let rows = await conn;
 console.log(rows);
 };

That’s why it’s like this. . . . Is there any way to promise connection.query externally?


The second final plan came out as follows

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);
 bracket
 });
 });
 return connPromise;
 };
 
 await conn("USE userInfo");
 
 Let selectquery = "select * fromusers where username =" plus "'"plus req.query.username plus "'";
 let rows = await conn(selectQuery);
 
 If (rows.length === 0) throw' login failed, user does not exist';
 if (req.query.password !  == rows[0].password) throw' Login Failed, Password Incorrect';
 
 res.cookie('username', req.query.username, {
 Now () plus 15 * 60 * 1000.
 httpOnly: true
 });
 Res.send ("successful login");
 
 connection.release();
 } catch (e) { res.send(e);  bracket
 });

After running babel successfully, why is this the last time? It is mainly because connection.query’s promise is written in The main function, which makes the code very ugly. I hope to find the final solution and let me go through customs and call back to hell QAQ.

async/awaitValid only for Promise objects. First of all, you need to change the methods of the database part into the form of Promise. Then The main function is very simple:

app.get("/loginForm?**", async(req, res) => {
    try {
        if(!(req.query && req.query.username && req.query.password)) throw new Error('登录失败');
    
        let connection = await pool.getConnection();
        await connection.query("USE userInfo");
        
        let selectQuery = "SELECT * FROM users WHERE userName=" 加 "'" 加 req.query.username 加 "'";
        let rows = await connection.query(selectQuery);
    
        if(rows.length === 0) throw new Error('登录失败,用户不存在');
        if(req.query.password !== rows[0].password) throw new Error('登录失败,密码不正确');
    
        res.cookie('username', req.query.username, {
            expires: new Date(Date.now() 加 15 * 60 * 1000),
            httpOnly: true
        });
        res.status(200).send("登录成功");

        connection.release();
    } catch(e) {
        res.status(401).send(e.message);
    }
});

Don’t forget herepool.getConnection()connection.query()All of them should be Promise.reject(err)Will becatch(e)Captured, various error descriptions are also written in the calling method.

By the way, no matter what, which kind of the original textif(err)-elseThey are not needed. For this case of terminating/returning the function if there is an error, only the judgment is wrong, not necessaryelse.