Как запросить MySQL перед запуском http-сервера в nodejs

Простой вопрос, я использую nodejs для службы HTTP restful API. Теперь я хочу запросить некоторые данные MySQL перед запуском http-сервера, фрагмент кода:

var price = -1;  
var userId = 'some user provided value';  
var sql    = 'SELECT max(price) FROM users WHERE id = ' + connection.escape(userId);  
connection.query(sql, function(err, results) {  
  price = results.price;  
});

server = http.createServer(function (request, response) {  
      handler(request);   //response depend on price
}).listen(8012); 

Итак, как совместить запрос MySQL и код http-сервера?

2 ответа

Хотя это простой вопрос, размер ответа огромен! Тим Раффлс прочитал целую лекцию на эту тему в Лондонской группе пользователей узлов на этой неделе (июль 2013 года), которая доступна в виде видеолекции [http://www.youtube.com/watch?v=nHXKA82M-LY].

Проблема здесь заключается в том, как обрабатывать что-то, что необходимо делать синхронно (последовательно) при работе в среде асинхронного (без порядка) программирования.

Из списка способов, которые Тим использует для решения этой проблемы, есть три, которые могут вам здесь помочь.

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

var price = -1;  
var userId = 'some user provided value';  
var sql    = 'SELECT max(price) FROM users WHERE id = ' + connection.escape(userId);  
connection.query(sql, function(err, results) {  
  price = results.price;  
  //start the server afer the sql connection has called back
  server = http.createServer(function (request, response) {  
      handler(request);   //response depend on price
  }).listen(8012); 
});

Однако это приводит к так называемому "коду пирамиды" и может довольно быстро стать неуправляемым.

Мое личное предпочтение для решения этой проблемы - использовать асинхронную библиотеку [https://github.com/caolan/async]wich, которая содержит арсенал инструментов для решения проблем секвенирования в узле. Я выбираю это, потому что это кажется мне наиболее интуитивным способом.

var async = require('async');

functon query(callback){
var price = -1;  
var userId = 'some user provided value';  
var sql    = 'SELECT max(price) FROM users WHERE id = ' + connection.escape(userId);  
connection.query(sql, function(err, results) {  
  price = results.price;  
  callback();
});

}

    function boot(callback){
    server = http.createServer(function (request, response) {  
          handler(request);   //response depend on price 
           callback();
    }).listen(8012); 
    }

    async.series([query,boot]);

Вы можете установить async с помощью npm install async.

Или третий подход, который может быть разумно использован для решения этих проблем, заключается в использовании обещаний. Они хорошо приняты, поскольку, изучая ноды, исходящие из языка, отличного от javascript, я обнаружил, что это довольно трудно приспособить к переходу с языка, отличного от javascript, но программисты, которые используют JQuery, похоже, одобряют этот подход. Здесь вы найдете руководство по использованию обещаний в node.js: http://howtonode.org/promises

Тим, конечно, дает гораздо более глубокий анализ и сравнение в своей лекции об этих подходах и дает несколько идей о том, как мы могли бы сделать это в будущем.

Вы также можете найти модули Express, Restify и Restler полезными в качестве способа создания API Restful.

* Отказ от ответственности Я не запускал этот код, так как у меня не установлен mysql - возможность для редактирования здесь:)

Вы просто добавляете сервер внутри обратного обратного вызова для запроса соединения, например:

var price = -1;  
var userId = 'some user provided value';  
var sql    = 'SELECT max(price) FROM users WHERE id = ' + connection.escape(userId);  
connection.query(sql, function(err, results) {  
  price = results.price;  
  server = http.createServer(function (request, response) {  
    console.log(price);
    handler(request, price, response);   //response depend on price
  }).listen(8012); 
});
Другие вопросы по тегам