Javascript 异步/等待nodejs mysql函数

Javascript 异步/等待nodejs mysql函数,javascript,mysql,node.js,express,Javascript,Mysql,Node.js,Express,我对nodejs有一个问题,实际上,正如你从我通过googledrive链接输入的两个模块中所看到的,我对登录表单有一个问题,因为尽管我在两个函数调用中都输入了asyn/await,但它并没有等待,但它仍然会继续,事实上它将返回变量打印为未定义。提前感谢所有回答问题的人 Router.js: router.post('/ajax/login', function(req, res, next) { (async () => { var loginDb = await login.logi

我对nodejs有一个问题,实际上,正如你从我通过googledrive链接输入的两个模块中所看到的,我对登录表单有一个问题,因为尽管我在两个函数调用中都输入了asyn/await,但它并没有等待,但它仍然会继续,事实上它将返回变量打印为未定义。提前感谢所有回答问题的人

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;

可以对返回承诺的函数使用wait

将login.js更改如下:

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内置了对承诺的支持。我建议使用mysql2。 mysql2文档中的示例代码:

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]);
}
另外,使用try-catch块处理错误:

try {
      const [rows, fields] = await connection.execute('SELECT * FROM `table` 
  WHERE `name` = ? AND `age` > ?', ['Morty', 14]);
}
catch(err) {
 handle error here
}
从login.js的运行方式来看,似乎必须提供回调函数才能从中获得结果

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;
然后在你的router.js中,你这样称呼它 路由器.js


路由处理程序中使用的IIFE是不必要的…

Wait仅在等待承诺时才执行有用的操作。如果您使用的是原始的mysql库,那么它不做任何承诺,所以您的Wait什么也不做。您需要使用该库来实现内置的promise支持,或者必须使用一个为mysql提供promise包装的外部库。我还建议您阅读async和Wait实际上是如何工作的,以便更好地了解它们是如何工作的以及它们在哪里工作的。所以很多人认为wait有一些神奇的功能,可以只等待一些异步操作。事实并非如此。此外,作为一个设计警告,您几乎永远不会将wait与传统回调结合使用,因为传统回调是没有promise接口的标志。因此,await conn.connectsomeCallback永远不会是使用await编写代码的方式。对于数据库API,使用promise包装器比在这个级别手动promisify要好得多。这样做会导致各种各样的问题和缺乏代码重用。在将承诺与嵌套回调混合在一起时很容易出错,我已经发现了一些错误。Promisify底层异步操作,并使用承诺逻辑来控制流,而不是回调逻辑和承诺逻辑的混合。
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 });
    });
})