Javascript.RU

Создать новую тему Ответ
 
Опции темы Искать в теме
  #1 (permalink)  
Старый 29.09.2019, 21:59
Аспирант
Отправить личное сообщение для diakon Посмотреть профиль Найти все сообщения от diakon
 
Регистрация: 28.09.2009
Сообщений: 49

Класс и возрат результата
Только начал изучать Node.js. До этого писал как на php так и на python. Но в ноде все своеобразное. Я хочу сделать класс соединения с БД, и 2мя методами - получения данных и вставики данных (selec и insert) в БД. Я сделал класс

class Db {
    constructor() {
        this.mysql = require('mysql');

        this.sql = this.mysql.createConnection({
            host: "127.0.0.1",
            database: "sql-test-db",
            user: "root",
            password: ""
        });
        this.sql.connect(function(err) {
            if (err) throw err;
        });
    }

    query(sql) {
        this.sql.query(sql, function (err, result) {
            if (err) throw err;

            return result;
        });
    }

    insert(sql, params) {
        this.sql.query(sql + ' ?', params, (err, results, fields) => {
            if (err) throw err;
        })
    }
}
module.exports = Db;

Далее в файле index.js я его получаю и пытаюсь передать в переменную результат SELECT запроса

const Db = require(__dirname + '/models/Db');

let db = new Db();
let result = db.query("SELECT * FROM tbl_chat_room_users");
console.log(result);

Но в итоге получаю undefined Я понимаю, что это связано с тем, что нода асинхронный язык и в момент выполнения console.log(result); в result еще не пришли данные из класса Db, но как тогда реализовывать работу с классами? Я пытался решить проблему через события. Сделать так что бы в db.query вместо return создавалось событие emit('returnSql', result), а потом вне класса (в index.js) пытаться его ловить на on, но ничего не сработало да и выглядит кастыльно. Можете подсказать, в чем я ошибся? Заранее спасибо!
Ответить с цитированием
  #2 (permalink)  
Старый 29.09.2019, 23:42
Аспирант
Отправить личное сообщение для diakon Посмотреть профиль Найти все сообщения от diakon
 
Регистрация: 28.09.2009
Сообщений: 49

Я так же пробовал переписать класс на async / await
class Db {
    constructor() {
        this.mysql = require('mysql');

        this.sql = this.mysql.createConnection({
            host: "127.0.0.1",
            database: "fastweb-yii2",
            user: "root",
            password: ""
        });
        this.sql.connect(function(err) {
            if (err) throw err;
        });
    }

    async query(sql) {
        return await this.sql.query(sql, function (err, result) {
            let reultsQuery = {};
            if (err) throw err;
            result.forEach(function(rowData, index) {
                reultsQuery[index] = rowData;
            });

            return reultsQuery;
        });
    }

    insert(sql, params) {
        this.sql.query(sql + ' ?', params, (error, results, fields) => {
            if (error) { throw error }
        })
    }
}
module.exports = Db;


но в результате возвращает Promise { <pending> }
Можнете сказать в чем ошибка?

Последний раз редактировалось diakon, 30.09.2019 в 00:30.
Ответить с цитированием
  #3 (permalink)  
Старый 30.09.2019, 00:32
Аватар для Aetae
Тлен
Отправить личное сообщение для Aetae Посмотреть профиль Найти все сообщения от Aetae
 
Регистрация: 02.01.2010
Сообщений: 6,587

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

1. Классическое решение: забыть про построчное написание кода и передавать вторым параметром callback и вызывать оный по завершению запроса.
//...
  query(sql, callback) {
        this.sql.query(sql, function (err, result) {
            if (err) throw err;
 
            callback(result);
        });
}
//...
function nextStep(result) {
   console.log(result);
}
db.query("SELECT * FROM tbl_chat_room_users", nextStep);

Современное решение: использовать async/await и выполнять нужную цепочку в рамках async функции:
(async function(){

  let result = await db.query("SELECT * FROM tbl_chat_room_users");
  console.log(result);
  //...

}())
__________________
29375, 35

Последний раз редактировалось Aetae, 30.09.2019 в 00:44.
Ответить с цитированием
  #4 (permalink)  
Старый 30.09.2019, 01:40
Аспирант
Отправить личное сообщение для diakon Посмотреть профиль Найти все сообщения от diakon
 
Регистрация: 28.09.2009
Сообщений: 49

Но вот в том то и дело, что хочется реализовать CMV модель, где классы выполняли классическую роль - возвращая данные, а не выполняли те функции, которые должен делать контроллер - частная обработка данных. Неужели в node (читай js) это так плохо реализуется?
Ответить с цитированием
  #5 (permalink)  
Старый 30.09.2019, 02:10
Аватар для Aetae
Тлен
Отправить личное сообщение для Aetae Посмотреть профиль Найти все сообщения от Aetae
 
Регистрация: 02.01.2010
Сообщений: 6,587

Асинхронность, паря, асинхронность. Не сделаешь ты асинхронне операции синхронными. В любых языках. Классы тут не при чём.
__________________
29375, 35
Ответить с цитированием
Ответ



Опции темы Искать в теме
Искать в теме:

Расширенный поиск


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Owl Carousel - добавить и удалить класс при смене слайда ethereal Элементы интерфейса 1 08.08.2019 22:47
Подскаите как менять класс у елемента в зависимость от класса другово елемента NirVanea Общие вопросы Javascript 4 10.09.2015 13:51
Добавить / удалить класс кликом fabrique Общие вопросы Javascript 4 03.09.2014 04:43
Изменить класс родительского элемента STyLe Общие вопросы Javascript 1 29.05.2014 20:21
Как удалить класс у соседних элементов housewm Events/DOM/Window 4 11.03.2014 13:29