Видимость this в Class
Приветствую,
const postgresql = require('pg-promise-simple'); const connectionString = "строка подключения к базе данных"; class Database { constructor() { postgresql.connect(connectionString).then(connection => { this.database = connection.client; }).catch(error => { this.database = 0; }); } getDatabase() { return this.database; // Всегда возвращает undefined // Хотя должен вернуть либо json либо 0 } } module.exports.Database = Database; this.database инициализируется в конструкторе. А когда вызывается метод класса getDatabase this.database уже underfined. Работа с классом происходит вот так: const database = require('.../database.js'); data = new database.Database(); console.log(data.getDatabase()); После отработки программа не завершается, а продолжает висеть в памяти. 1. Что делаю не так, почему this.database равен underfined в методах класса, несмотря на инициализацию его в конструкторе; 2. Почему программа не завершается, а продолжает висеть в памяти. Как ее завершить принудительно? |
Цитата:
Могу дать пример для pg: const {Client} = require('pg') const {development: env} = require('../../../env.json') const database = new Client({ connectionString: env.DATABASE_CONNECTION_URI }) database.connect() // ON -> promise // ... database.end() // OFF -> promise |
Ок. Спасибо за ответ.
А как на счет этого: getDatabase() { return this.database; // Всегда возвращает undefined // Хотя должен вернуть либо json либо 0 }Почему JavaScript записывает в переменную this.database, но потом внутри метода этого же класса не может ее прочитать? |
Elfix, потому что асинхронность:
data = new database.Database(); //1. пошёл коннект к базе console.log(data.getDatabase()); //2. запрос несуществующей переменной //3. ... //4. соединение установилось, переменная задана |
Благодарю. Как это победить?
|
Не делать в конструкотре асинхронных вещей.)
|
Ха, прекрасный совет: чтобы не было проблемы - не создавай ее? :)
А если серьезно. Мне нужно чтобы коннкшн к базе был где-то сохранен и использовался несколько раз. А вот сами запросы было бы неплохо, чтобы запускались асинхронно. Как это сделать? Т. е. мне нужно чтобы программа при connect как-то зависла, пока этот connect не отработает, а потом уже пользоваться всеми прелестями асинхронности. |
Думаю, это всё, что нужно для этого модуля подключения/отключения:
const postgresql = require('pg-promise-simple'); const connectionString = "строка подключения к базе данных"; postgresql.connect(connectionString); function disconnectDB() { postgresql.end(); } module.exports = postgresql; exports.disconnectDB = disconnectDB; А then и catch делать уже "на месте". |
Elfix, nerv_ показал как. При создании класса никакого коннекта. Отдельный метод connect, возвращающий промис. database.connect().then().then()....then();
|
Ок. Бог с ним с классом.
Попробую по-другому объяснить. Вот такой код работает: const postgresql = require('pg-promise-simple'); const connectionString = "строка подключения"; var client; postgresql.connect(connectionString).then(connection => { client = connection.client; client.query('Мой запрос на SQL').then(result => { console.log(result); client.end(); }); });Все отлично работает. Но есть недостаток - я подключился к базе, выполнил запрос и отключился от нее. Нет возможности пользоваться подключением в переменной connect. Я воспользовался соединением и закрыл его. Вот такой код не работает: const postgresql = require('pg-promise-simple'); const connectionString = "строка подключения"; var client; postgresql.connect(connectionString).then(connection => { client = connection.client; }); // В этом месте нужно как-то зависнуть, пока переменной client не будет присвоено значение client.query('Мой запрос на SQL').then(result => { console.log(result); });Второй код уже не работает. Вот мне нужно как-то так сделать, чтобы у меня был коннект к базе и я им всегда мог пользоваться. пример nerv_ не подходит, так как просто вызвав connect у меня отсутствует информация о подключении, и мне нужно then вызывать и этот же then как-то останавливать пока нужный connection.client не будет получен... |
Если утрировать:
function mainExecutionStream(connection){ //здесь ВЕСЬ код } postgresql.connect(connectionString).then(mainExecutionStream); А так код должен быть разбит на методы и функции вызывающие друг друга. Ну и ещё по новомодному можно так: ( async function mainExecutionStream(connection){ var connection = await postgresql.connect(connectionString); //здесь ВЕСЬ код }())только следует помнить, что async/await - это не sleep никакой, а обёртка над промисами. |
В общем победил. Воспользовался немного другим классом для этого.
В целом мой класс получился вот таким: const connectionString = "Строка подключения"; const {Pool} = require('pg'); class Database { constructor (autoConnect = false) { if (autoConnect) this.connect(); } connect() { this.pool = new Pool({ connectionString: connectionString }); } disconnect() { this.pool.end(); } query(sql, func) { this.pool.query(sql, (error, result) => { func(error, result); }); } } const database = new Database(true); database.query('Мой код SQL', (error, result) => { console.log(result); }); database.disconnect(); |
Не другим классом воспользовался, а другим драйвером.
|
Часовой пояс GMT +3, время: 19:26. |