简体   繁体   中英

Async/Await nodejs mysql function

I have a problem with nodejs, in practice as you can see from the two modules that I entered via google drive link, I have a problem with the login form because although I have entered asyn / await in both the functions calls it does not wait but it goes on anyway and in fact it prints the return variable as "undefined". Thanks in advance to everyone who answers!

Router.js :

router.post('/ajax/login', function(req, res, next) {
 (async () => {
var loginDb = await login.login(req.body.matricola, req.body.password);

console.log(loginDb);
res.json({output: loginDb, matricola: req.body.matricola});
 })();
})

login.js

var response;
async function login(matricola, password){

var conn = connect();

await conn.connect(function(err){
if(!err){
  //query ricerca utente nel db
  password = md5(password); //cifro la password
  conn.query("SELECT * FROM user WHERE matricola=? AND password=?",[matricola, password] 
,function(err, result){
    if(!err){
      if(result.length == 1 && matricola == result[0].matricola && password == result[0].password){
        //Invio segnale di logged-in al client
        response = "logged-in";

      }
      else{
       response = 'error-login';
      }
     }
   })
  }
  else{
  response = 'error-db';
  }
})

return response;

}

exports.login = login;

you can use await on a function that returns a promise.

Change login.js something as below:

function login(matricola, password){

    return new Promise(function(resolve,reject){
     conn.connect(function(err){
       if(!err){
      //query ricerca utente nel db
       password = md5(password); //cifro la password
        conn.query("SELECT * FROM user WHERE matricola=? AND password=?",[matricola, password] 
      ,function(err, result){
        if(!err){
           if(result.length == 1 && matricola == result[0].matricola && password == result[0].password){
            //Invio segnale di logged-in al client
            resolve("logged-in")
          }
           reject(err);
         }
       })
      }
      reject(err)
    })
    }) 
    }

Mysql2 has inbuilt support for promises. I would recommend using mysql2.
Sample code from mysql2 documentation:

async function main() {
  // get the client
  const mysql = require('mysql2/promise');
  // create the connection
  const connection = await mysql.createConnection({host:'localhost', user: 'root', database: 'test'});
  // query database
  const [rows, fields] = await connection.execute('SELECT * FROM `table` WHERE `name` = ? AND `age` > ?', ['Morty', 14]);
}

Also, use try-catch block to handle errors :

try {
      const [rows, fields] = await connection.execute('SELECT * FROM `table` 
  WHERE `name` = ? AND `age` > ?', ['Morty', 14]);
}
catch(err) {
 handle error here
}

From the way your login.js flows, it looks like you'll have to supply a callback function to get the result from it.

login.js

function login (matricola, password, cb) {
    const conn = connect();

    conn.connect (function(err){
        // If there's an error in setting up the connection to db, terminate immediately
        if (err) return cb (new Error("DB connection error"));

        const hashedPassword = md5 (password);
        const query = "SELECT * FROM user WHERE matricola=? AND password=?";
        conn.query (query, [matricola, hashedPassword], function (err, result) {
            // If there's an error with the query, terminate immediately
            if (err) return cb(new Error("Query error"));

            // Matricola and passwords match, so return a positive response
            if (result.length === 1 && matricola === result[0].matricola && hashedPassword === result[0].password) 
                return cb (null, result[0]);
            return cb (new Error("User not found"));
        });
    });
}

exports.login = login

Then in your router.js , you call it like so router.js

router.post ('/ajax/login', function (req, res, next) {
    login.login (req.body.matricola, req.body.password, function (err, result) {
        if (err) return res.status(401).send("Invalid matricola/password");
        res.json ({ output: result, matricola: req.body.matricola });
    });
})

The IIFE used within the route handler is unnecessary...

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM