Javascript.RU

Создать новую тему Ответ
 
Опции темы Искать в теме
  #1 (permalink)  
Старый 17.03.2016, 11:14
Новичок на форуме
Отправить личное сообщение для zobretatel Посмотреть профиль Найти все сообщения от zobretatel
 
Регистрация: 02.12.2015
Сообщений: 5

как правильно дождаться данных
С node.js только столкнулся . Вопрос который задам , наверное относится к избитым ,
но попробовав разные нагугленные варианты проблему решить не удалость.

Суть такова :
1) есть стандартный http сервер , получающий запрос и выдающий ответ
2) есть запрос к ms sql серверу за данными
3) данные успешно извлекаются , но как их передать ПОСЛЕ извлечения не знаю
4) пробовал делать задержку ( цикл for( var i... ){ timeout(); } )
5) ответ на sql запрос получают всегда после окончания работы функции
getMSSQLData , независимо от величины задержки , делал её для эксперимента
достаточно большой .

Вопросы :
1) не понимаю , почему ответ на sql запрос приходит ВСЕГДА после окончания работы
getMSSQLData , независимо от величины задержки , хоть секунда , хоть несколько минут .
Получается , что функция query(...) ставиться в какую-то очередь на выполнение,
а реальное выполнение начинается... КОГДА ?
2) пробовал "подождать" данные внутри getMSSQLData конструкцией типа
while( Line === '' ){} получал зависание

// стандартный http-сервер
...
var Response = httpDat.get(path);
response.writeHead( Response.Error , { 'Content-Type':Response.MIME } );
response.write( Response.Page );
response.end();
...


код был примерно такой :
function getMSSQLData(xServer , xDB , xUser , xPass , xQuery){

     Line = '';

     query(xServer , xDB , xUser , xPass , xQuery);

     for( var i=0 ; i<10 ; i++ ){
           timeout();
     }

     // while( Line === '' ){};

     return( Line );

}



function query(xServer , xDB , xUser , xPass , xQuery){
	sql.connect("...").then(function() {
		new sql.Request().query("SELECT ... FROM ...").then(function(recordset) {
			for( var i=0 ; i<recordset.length ; i++ ){
				Line += recordset[i].DT + '   ::   ' + recordset[i].Val + '\n';
			}
			console.log('result query:'+Line);
			Flag = true;
		});
	});	
}

function timeout(){
       // несколько ненужных вычислений для формирования задержки
}


пробовал async , возможно неправильно , потому, что не помогло

Главный вопрос :
КАК ПРАВИЛЬНО ДОЖДАТЬСЯ ПОЛУЧЕНИЯ ДАННЫХ ОТ MS SQL и ПЕРЕДАТЬ ИХ В КАЧЕСТВЕ ОТВЕТА НА HTTP-запрос ?
Ответить с цитированием
  #2 (permalink)  
Старый 17.03.2016, 14:42
Новичок на форуме
Отправить личное сообщение для andryxx Посмотреть профиль Найти все сообщения от andryxx
 
Регистрация: 15.06.2015
Сообщений: 5

у вас все не по-джедайски.
во-первых, формирование задержек для получения ответов есть зло. тем более таким способом. вы "подвешиваете" сервер на время таймаута. вся прелесть асинхронности node.js теряется.

куда вам следует копать:
во-первых, используйте нормальный, современный способ обмена данными между клиентом и сервером, напрмер на основе вебсокета можно как здесь, либо через socket.io, в конце концов XmlHttprequest.
во-вторых, ответ отправляйте в функции-коллбэке, запускаемой по факту получения ответа от MS SQL
Ответить с цитированием
  #3 (permalink)  
Старый 17.03.2016, 20:23
Аватар для Coriolan161
Профессор
Отправить личное сообщение для Coriolan161 Посмотреть профиль Найти все сообщения от Coriolan161
 
Регистрация: 21.11.2015
Сообщений: 440

zobretatel,
попробуй запихать задержку в функцию query
Ответить с цитированием
  #4 (permalink)  
Старый 17.03.2016, 21:38
Аватар для MallSerg
Профессор
Отправить личное сообщение для MallSerg Посмотреть профиль Найти все сообщения от MallSerg
 
Регистрация: 07.03.2011
Сообщений: 1,126

JS строго однопоточен и никак иначе.
Даже если небо начнет падать на землю return будет вызван раньше чем выполнится любая асинхронная операция (т.е. использование задержки это полное непонимание основ работы JS).
Ответить с цитированием
  #5 (permalink)  
Старый 18.03.2016, 08:45
Новичок на форуме
Отправить личное сообщение для zobretatel Посмотреть профиль Найти все сообщения от zobretatel
 
Регистрация: 02.12.2015
Сообщений: 5

andryxx
Цитата:
1) все не по-джедайски ... формирование задержек есть зло
2) используйте нормальный, современный способ обмена данными между клиентом и сервером, напрмер на основе вебсокета можно как здесь, либо через socket.io
1) да , зло . понимаю . в данном случае у меня нет толп клиентов, данные будут забираться достаточно редко, примерно раз в час одним , максимум тремя клиентами (одним из клиентов может быть не браузер, а другой сервер). поэтому подвешивание сервера в данном случае меня не беспокоит.
2) спасибо . раздумываю, попробовать socket или делать выборку из sql заранее , а при запросе возвращать уже готовые данные .

Для интереса напичкал код console.log(..) и вот что получилось :
1) стартует getMSSQLData()
2) стартует query()
3) стартует sql.connect() внутри query()
4) стартует запуск цикла timeout() внутри getMSSQLData()
5) ЗАВЕРШАЕТСЯ getMSSQLData()
6) стартует new sql.Request().query() внутри query()
7) приходит ответ на sql.Request

Coriolan161
Цитата:
задержку в функцию query
попробовал . после sql.connect со всем вложениями . не помогло , почему ) опять не понимаю . ведь запрос к sql уже отослан .

MallSerg
Цитата:
это полное непонимание основ работы JS)
спасибо профессор , с полным непониманием основ JS всё в порядке )

Спасибо друзья
в общем либо , socket попробую , либо кэшировать ответы от sql заранее , так как в принципе понятно , что будет выбрано .
Наверно, из-за соображений времени, сейчас сделаю кэш , но к socket'у обязательно вернусь .
Ответить с цитированием
  #6 (permalink)  
Старый 18.03.2016, 13:36
Аспирант
Отправить личное сообщение для Max Power Посмотреть профиль Найти все сообщения от Max Power
 
Регистрация: 15.12.2015
Сообщений: 83

Комрады, я если честно вообще не понял в чем проблема, но дело пахнет кошмаром и попыткой пристрелить себя в ногу на ровном месте.

Почему нельзя писать простые вещи просто?

var app = module.exports = require('koa')();
var knex = require('koa-knex');
var conf = require('./conf');

app.use(knex(conf.knexConnection));

app.use(function* showUsers() {
  this.body = yield this.knex
    .select('firstname', 'lastname')
    .from('users')
    .where('is_active', true);
});

if (!module.parent) {
  app.listen(conf.app.port, conf.app.host);
  console.log(`listening on http://${conf.app.host}:${conf.app.port}/`);
}

// Выведет JSON:
// [{firstname: 'Маша', lastname: 'Иванова'}, 
// {firstname: 'Вася', lastname: 'Пупкин'}]


PS: А не пахнет ли здесь вообще попыткой вызвать асинхронное синхронно?!!!

Последний раз редактировалось Max Power, 18.03.2016 в 13:53.
Ответить с цитированием
  #7 (permalink)  
Старый 18.03.2016, 14:29
Новичок на форуме
Отправить личное сообщение для zobretatel Посмотреть профиль Найти все сообщения от zobretatel
 
Регистрация: 02.12.2015
Сообщений: 5

Max Power
выглядит интересно .

а кстати генераторы не решают проблему асинхронности ?
Ответить с цитированием
  #8 (permalink)  
Старый 19.03.2016, 00:27
Профессор
Отправить личное сообщение для Яростный Меч Посмотреть профиль Найти все сообщения от Яростный Меч
 
Регистрация: 12.04.2010
Сообщений: 557

насколько я понял, в этом sql используются промисы. Тогда можно так:

function getMSSQLData(xServer , xDB , xUser , xPass , xQuery){
    return sql.connect("...")
        .then(function() {
            return new sql.Request().query("SELECT ... FROM ...");
        })
        .then(function(recordset) {
            var Line = '';
            for( var i=0 ; i<recordset.length ; i++ ){
                Line += recordset[i].DT + '   ::   ' + recordset[i].Val + '\n';
            }
            console.log('result query: ' + Line);
            return Line;
        });
}

// использование
getMSSQLData(...).then(function(Line) {
    // вот здесь работаем с Line
});
Ответить с цитированием
  #9 (permalink)  
Старый 22.03.2016, 05:25
Аспирант
Отправить личное сообщение для Max Power Посмотреть профиль Найти все сообщения от Max Power
 
Регистрация: 15.12.2015
Сообщений: 83

> а кстати генераторы не решают проблему асинхронности

Да, решают. Хотя это в среде теоретиков принято считать хаком (да, собственно, так оно и есть)), на практике это работает неплохо уже сейчас.

Пока все ждут async/await в Ноде, можно красиво писать на генераторах без ада коллбеков и обработки ошибок через 3 строчки уже сейчас.
Ответить с цитированием
Ответ



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

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


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Как вы относитесь к наркоманам? Maxmaxmaximus7 Оффтопик 7 05.02.2014 12:29
Пасоны, как правильно парсить параметры? megaupload Оффтопик 15 05.05.2013 14:44
Как правильно прицепить обработку события slowklg Events/DOM/Window 6 15.03.2012 15:20
Как правильно очистить maxlength в input? Маэстро Events/DOM/Window 10 22.06.2011 18:14
Как правильно оформить Send() Алекс97 AJAX и COMET 20 30.10.2008 19:19