Почему получаю верный ответ от БД, но в вызывающем методе undefined?

Где я допустил ошибку?

Есть метод:

async getUsers(req, res) {
        try {
            const result =  await db.query('SELECT * FROM users')
            console.log(result);
            res.status(200).json(result)
        } catch (e) {
            console.log(e)
        }
    }

Через него посылаю запрос на метод класса DB:

 async query(str){
        const connection = mysql.createConnection(DB_config)
        try{
             connection.connect()
             connection.query(str, function(err, rows, fields) {
                if (err) throw err
                return JSON.stringify(rows)
            });
        }
        catch(e){
            console.log(e)
        }
        connection.end();
    }

В методе класса DB, получаю верный ответ от MySQL, но он не доходит в вызывающий метод, там просто undefined.

Думаю, что опять с асинхронностью наворотил, но не пойму, где точно.


Ответы (2 шт):

Автор решения: nörbörnën

Конкретно этот кейс можно решить завернув вызов connection.query в Promise:

async query(sql) {
  return new Promise((resolve, reject) => {
    const connection = mysql.createConnection(DB_config)
    connection.connect((err) => {
      if (err) {
        reject(err);
      }
    });

    connection.query(sql, (err, rows) => err ? reject(err) : resolve(rows));

    connection.end();
  });
}

Но тут много плохих практик:

  • создание коннекта на каждый запрос - плохо
  • ручное заворачивание в Promise - не удобно для новичка

Используйте mysql2 и создавайте один коннект (пулл коннектов) к базе данных для всего приложения (см. ответ).

→ Ссылка
Автор решения: dmitriy_vlz

Переделанный вариант: Имеем "драйвер" :

const mysql = require('mysql2/promise')
const DB_config = require('../config/db.config')
const db = mysql.createPool(DB_config);


module.exports =  db

И в файлах приложения подключаем его и используем:

const db = require('../utils/db.utils')


class authController {
   
    async getUsers(req, res) {
        try {
            const [rows, fields] = await db.execute(`SELECT count(*) AS count FROM users WHERE Email = 'test'`)            
            console.log(JSON.stringify(rows));
            res.status(200).json(rows[0]['count'])
           
        } catch (e) {
            console.log(e)
        }
    }
}

module.exports = new authController()
→ Ссылка