Javascript-форум (https://javascript.ru/forum/)
-   Node.JS (https://javascript.ru/forum/node-js-io-js/)
-   -   Видимость this в Class (https://javascript.ru/forum/node-js-io-js/72757-vidimost-v-class.html)

Elfix 24.02.2018 09:42

Видимость 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. Почему программа не завершается, а продолжает висеть в памяти. Как ее завершить принудительно?

nerv_ 24.02.2018 10:04

Цитата:

Сообщение от Elfix
После отработки программа не завершается, а продолжает висеть в памяти.

потому, что disconnect нужно делать.

Могу дать пример для 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

Elfix 24.02.2018 13:10

Ок. Спасибо за ответ.
А как на счет этого:

getDatabase() {
        return this.database;
        // Всегда возвращает undefined
        // Хотя должен вернуть либо json либо 0
    }
Почему JavaScript записывает в переменную this.database, но потом внутри метода этого же класса не может ее прочитать?

Aetae 24.02.2018 13:18

Elfix, потому что асинхронность:
data = new database.Database();  //1. пошёл коннект к базе
console.log(data.getDatabase()); //2. запрос несуществующей переменной
//3. ...
//4. соединение установилось, переменная задана

Elfix 24.02.2018 13:31

Благодарю. Как это победить?

Aetae 24.02.2018 13:57

Не делать в конструкотре асинхронных вещей.)

Elfix 24.02.2018 14:18

Ха, прекрасный совет: чтобы не было проблемы - не создавай ее? :)
А если серьезно. Мне нужно чтобы коннкшн к базе был где-то сохранен и использовался несколько раз.

А вот сами запросы было бы неплохо, чтобы запускались асинхронно.
Как это сделать? Т. е. мне нужно чтобы программа при connect как-то зависла, пока этот connect не отработает, а потом уже пользоваться всеми прелестями асинхронности.

Audaxviator 24.02.2018 16:53

Думаю, это всё, что нужно для этого модуля подключения/отключения:
const postgresql = require('pg-promise-simple');
const connectionString = "строка подключения к базе данных";

postgresql.connect(connectionString);

function disconnectDB() {
  postgresql.end();
}
	 
module.exports = postgresql;
exports.disconnectDB = disconnectDB;

А then и catch делать уже "на месте".

Aetae 24.02.2018 17:17

Elfix, nerv_ показал как. При создании класса никакого коннекта. Отдельный метод connect, возвращающий промис. database.connect().then().then()....then();

Elfix 24.02.2018 18:25

Ок. Бог с ним с классом.

Попробую по-другому объяснить.
Вот такой код работает:
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 не будет получен...


Часовой пояс GMT +3, время: 03:47.