如何在 NodeJS 中对 MySQL 数据库进行异步调用

How to do async calls to MySQL database in NodeJS

更新:

我有一个异步函数如下:

async function userHandler(username, displayName, profilePicture, email) {
  connection = await connectDB()
    await connection.query('USE spyncdb;');
    await connection.query('SELECT * FROM users WHERE username = ?', [username], function(error, result, fields) {
      if (error) {
          console.log(error);
      }
      if (result) {
          if (result != 0) {
            console.log('User already in database')
            return result[0].user_id;
            // Do whatever should be done
            } else {
            // Add user to database
            connection.query('INSERT INTO users (username, displayname, profilePicture, email) VALUES (?, ?, ?, ?)', [username, displayName, profilePicture, email], function(error, result, fields) {
              if (error) {
                console.log('ERROR');
                console.log(error);
              }
              if (result) {
                console.log('user inserted into db');
                return;
              };
            })
            }
        }
    });
}

然后我调用这个函数,并希望从中存储 return 值 (user_id)。

我从以下调用函数:

async () => {
    let user_id = await userHandler(aUser.username, aUser.displayName, 
    aUser.profilePicture, aUser.email);
    
     console.log(user_id);
}

但我只得到“未定义”- 为什么?

PS。我将 mysql 库用于我的数据库连接。

有两种解决方法。最简单的,不要使用回调,使用 Promises 然后:

aUser.user_id = await userHandler

或者您必须提供回调函数并相应地同步您的代码:

function example(cb) {
  userHandler(..., function(result) {
    cb(user_id);
  });
}

example(function(user_id) {
  aUser.user_id = user_id;
});

记住,回调驱动的代码实现和使用非常不有趣,所以如果可以的话,如果不完整,请转向 Promises async/await.

此处的一般规则是如果您的函数进行回调以获得答案,您必须接受可以链接的回调。来自回调函数的 return 几乎总是 被扔进垃圾桶并被忽略

好的,我终于设法解决了这个问题。必须做的主要事情是从基于回调的代码切换到更现代的 async/away 方式来处理异步代码,这使代码更简单,更易于处理和阅读。

另外我从mysql库切换到mysql2库,后者更适应异步函数。最终代码如下所示:

const mysql2 = require('mysql2/promise');


// Connect to server
const pool = mysql2.createPool({
    host     : "ENDPOINT",
    user     : "USERNAME",
    password : "PASSWORD",
    port     : "3306",
    database : "DATABASENAME",
    waitForConnections: true,
    connectionLimit: 10,
    queueLimit: 0
});

// Function for checking the user in the database
async function checkUser(username, displayName, profilePicture, email) {
  const result = await pool.query('SELECT * from users WHERE username = ?', [username]);
  if (result[0].length < 1) {
    console.log('User not found, adding new user...');
    const newResult = await pool.query('INSERT INTO users (username, displayname, profilePicture, email) VALUES (?, ?, ?, ?)', [username, displayName, profilePicture, email]);
    return newResult[0].insertId;
  }
  console.log('User found in DB')
  return result[0][0].user_id;
}

// Calling the check function with the input values from the user
async function check() {
let user = await checkUser(aUser.username, aUser.displayName, aUser.profilePicture, aUser.email);
console.log(`user ID is: ${user}`);
}

// Invoking the check function      
check();