как правильно дождаться данных
С 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-запрос ? |
у вас все не по-джедайски.
во-первых, формирование задержек для получения ответов есть зло. тем более таким способом. вы "подвешиваете" сервер на время таймаута. вся прелесть асинхронности node.js теряется. куда вам следует копать: во-первых, используйте нормальный, современный способ обмена данными между клиентом и сервером, напрмер на основе вебсокета можно как здесь, либо через socket.io, в конце концов XmlHttprequest. во-вторых, ответ отправляйте в функции-коллбэке, запускаемой по факту получения ответа от MS SQL |
zobretatel,
попробуй запихать задержку в функцию query |
JS строго однопоточен и никак иначе.
Даже если небо начнет падать на землю return будет вызван раньше чем выполнится любая асинхронная операция (т.е. использование задержки это полное непонимание основ работы JS). |
andryxx
Цитата:
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 Цитата:
MallSerg Цитата:
Спасибо друзья в общем либо , socket попробую , либо кэшировать ответы от sql заранее , так как в принципе понятно , что будет выбрано . Наверно, из-за соображений времени, сейчас сделаю кэш , но к socket'у обязательно вернусь . |
Комрады, я если честно вообще не понял в чем проблема, но дело пахнет кошмаром и попыткой пристрелить себя в ногу на ровном месте.
Почему нельзя писать простые вещи просто? 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
выглядит интересно . а кстати генераторы не решают проблему асинхронности ? |
насколько я понял, в этом 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 }); |
> а кстати генераторы не решают проблему асинхронности
Да, решают. Хотя это в среде теоретиков принято считать хаком (да, собственно, так оно и есть)), на практике это работает неплохо уже сейчас. Пока все ждут async/await в Ноде, можно красиво писать на генераторах без ада коллбеков и обработки ошибок через 3 строчки уже сейчас. |
Часовой пояс GMT +3, время: 00:29. |