Как получить при вызове функции в конкретном случае node js при запросе к базе данных, не в консоли

Как мне получить значение переменной countUsers от функции querybd не в консоле, а в основном коде

...

function querybd(queryfun, check) {
    const mysql = require("mysql2");
    const connection = mysql.createConnection({
        "host": 'localhost',
        "user": "****",
        "database": "****",
        "password": "****",
        "port": "****"
    });

    // тестирование подключения
    connection.connect(function (err) {
        if (err) {
            return console.error("Ошибка: " + err.message);
        }
        else {
            console.log("Подключение к серверу MySQL успешно установлено");
        }
    });

    connection.query(queryfun, function (err, results, fields) {
        // данные значения отправить назад, а не в консоли
        console.log(results);
    });


    // закрытие подключения
    connection.end(function (err) {
        if (err) {
            return console.log("Ошибка: " + err.message);
        }
        console.log("Подключение закрыто");
    });
}

io.sockets.on('connection', function (socket) {
    socket.on('join', function (data) {
        queryforfunc = "SELECT count(distinct(`user`)) FROM chat WHERE `room` = '" + data.room + "'";
        countUsers = querybd(queryforfunc, true);
        // countUsers как мне получить значение переменной countUsers от функции querybd ???
    });

    ...

});

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

Автор решения: Sergei Kirjanov

"mysql2" поддерживает промисы, и можно использовать async/await:

const express = require('express')
const http = require('http')
const mysql = require('mysql2/promise')

const app = express()
const server = http.createServer(app)
const options = {}
const io = require('socket.io')(server, options)

app.get('/', (req, res) => {
    res.sendFile(__dirname + "/mysql_socket_client.html")
})

const queryDB = async (statementText,toBind) =>{
    const connection = await mysql.createConnection({
        host: "mysql",
        user: "root",
        password: process.env.MYSQL_PASSWORD,
    })
    try {
        const [rows,fields] = await connection.query(statementText,toBind)
        return rows
    } finally {
        connection.end()
    }
}

io.on('connection', async socket => {
    const [res,...rows] = await queryDB('SELECT ? + ? AS solution',[5,7])
    console.log(res)
    socket.emit('news', res)
})

server.listen(3000)

Функции "mysql2" API возвращают промисы. Чтобы превратить промис в результат, с которым можно работать, используется ключевое слово await. Это значит, что движку js можно подождать результата, занимаясь чем-то другим полезным.

await можно писать в функции, которая помечена как async, Такая функция тоже возвращает промис и может чего-то ждать. При вызове такой функции, в свою очередь, тоже можно использовать await и т. д.


node однопоточный, а sql запрос может быть долгим, и не хочется, чтобы вся система зависала ожидая его окончания.

Поэтому изначально API действий, внутри которых требовалось ожидание, делали на колбэках, но писать было очень тяжело -- лесенкой вложенных колбэков.

Потом появились промисы -- функция возвращала не запрашиваемое значение, а обещание его вернуть. Используя промисы, можно составлять сложные действия.

И, наконец, появились async/await и код стал выглядеть линейно, как будто и нет перерывов на ожидание.

→ Ссылка