@bagos

Как получить результат работы функции с вложенными функциями nodejs?

знаю что это не очень приветствуется, но задана глобальная переменная, она неизменна, мне нужно получить значение из базы и записать в эту переменную чтобы в дальнейших запросах restful приложения использовать эту переменную.
function getAlarmId(callback){
	connection.query('SELECT id from alarm where type=1', function(err, rows, result) {
		rows.forEach(function (alarm) {
	   		callback(alarm.id);
		});
return 2;
	});
return 1; // получаю только это значение, как в него передать callback?
}

такой вариант меня не устраивает
getAlarmId(function(res){
	...
});


нужно тото вроде
id = getAlarmId(); в id значение из базы
  • Вопрос задан
  • 1563 просмотра
Решения вопроса 1
MarcusAurelius
@MarcusAurelius Куратор тега Node.js
автор Impress Application Server для Node.js
Что глобальные переменные плохо - это не более, чем расхожее мнение, зачастую сводящееся к религиозному чувству. Приверженцы не могут рационально объяснить, почему именно нельзя. Все доводы о том, что это запутывает код, не выдерживают критики, ведь есть масса примеров, когда введение глобальной переменной наоборот упрощает код и делает его более понятным. Кроме того, в глобальной области видимости лежит куча всего нужного: console, setInterval, clearImmediate, parseInt, Infinity, Math, decodeURI, все встроенные классы и многое другое. Для браузеров еще: document и window. И даже require это глобальная переменная, апологеты почему-то не требуют писать var require = require('require'); Как же так, не порядок, require глобальный. Ересь глобальности затаиласт в самом сердце механизма внедрения зависимостей. На самом деле, не все эти идентификаторы действительно глабальные, и в Node.js могут быть контекты, не будет видно того же require, но сейчас не об этом. А о том, что использование глобальных переменных может давать как полезные, так и вредные плоды. В Вашем случае, вполне можно сделать так:
// Инициализация глобальной области
global.model = { // задаем значеня по умолчанию
  alarmId: null // можно поставить, например, -1 или в зависимости от задачи
};
// Функция получения 
function getAlarmId(callback) {
  connection.query('SELECT id from alarm where type=1', function(err, rows, result) {
    if (!err && rows.length === 1) {
      var row = rows[0];
      model.alarmId = row[Object.keys(row)[0]];      
    }
    if (callback) callback();
  });
}
// Можем теперь вызвать при старте приложения, обычно без колбека
getAlarmId();
// А по ходу исполнения можем вызывать его с колбеком, так и без колбека
getAlarmId(function() {
  console.dir(model);
)};
// Или обновлять по таймеру
setInterval(getAlarmId, 5000);

Но лучше всего, не дергать постоянно базу по таймеру или по запросу, а наоборот, сделать основным местом хранения значения - память, и сбрасывать в базу по таймеру, в отложенном режиме, и только если произошли изменения. База нужна нам будет только для постоянного сохранения, операции с ней медленные и асинхронные, а с памятью - быстрые и синхронные. Поэтому, исключив доступ к базе во время обработки HTTP (или других) запросов, мы резко подымаем производительность. Но все это уже не православный REST, а stateful-программирование. Рекомендую почитать еще тут: habrahabr.ru/post/204958 и тут habrahabr.ru/post/247543
Ответ написан
Комментировать
Пригласить эксперта
Ответы на вопрос 1
@iShatokhin
JS developer
Глобальная переменная действительно плохая идея, так вы еще хотите асихронный код выполнять синхронно :) Если мотивы первого требования понятны, то второго - нет.

Синхронность вам может обеспечить только адаптер вашей DB (в чем лично я сомневаюсь). Можно использовать Promise/await/yield генераторы, но код все равно останется асинхронным, хоть вы и запишите его в одну строчку.
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы