2015-09-29 2 views
6

Я работаю над созданием системы регистрации пользователей для веб-сайта, над которым я работаю, но у меня есть несколько проблем.Node.js Синхронные запросы с MySQL

Я стараюсь держаться подальше от необходимости гнездовых обратных вызовов, потому что он получает вид грязно, что мне нужно помочь в поиске, если есть способ создания синхронных запросов с узлом-Mysql

Вот что я Я пытаюсь достичь.

connection.query("select 1 as email from users where email = " + connection.escape(email), function(err, rows, fields) { 
    if(err) { 
     var error = { 
      error_message: err.code, 
      error_number: err.errno 
     }; 

     return res.send(error); 
    } 

    if(rows.length > 0) { 
     var error = { 
      message: 'Email Address is Taken', 
      code: 2 
     }; 
     return res.send(error); 
    } 
}); 

connection.query("insert into users (email, password) values ("+connection.escape(email)+", "+connection.escape(hash)+")", function(err, rows, fields) { 
      if(err) { 
       var error = { 
        error_message: err.code, 
        error_number: err.errno 
       }; 

       return res.send(error); 
      } 
     }); 

Моя цель состоит в том, чтобы первый запуск запроса и, если это возвращает строку, чтобы потом не выполнить второй запрос, но если первый запрос возвращает 0 строк затем продолжить и запустить второй запрос.

Я знаю, что я могу вложить второй запрос в первый запрос и поставить, если в другом, но это то, что я не хочу делать, потому что, хотя у меня есть эти два запроса, у меня также есть возможность использовать bcrypt для шифрования пароль, который также должен быть вложен.

Есть ли способ написать его так, что мне не нужно вставлять два запроса или вложенность их будет моим единственным вариантом?

+0

Вы должны гнездо их. –

+0

Не нужно использовать гнездование. Вы можете использовать async waterfall и передать переменную true/false между шагами. Если вы не можете запустить второй запрос, просто передайте значение false из первого. – CargoMeister

+4

Если вы собираетесь разрабатывать в node.js, вам нужно научиться писать хороший асинхронный код, поскольку это главный архитектурный элемент node.js, и если вы строите сервер, вам нужно использовать операции async для поддерживать чувство реагирования и масштабируемости сервера. Теперь можно начать. Я бы посоветовал узнать, как использовать обещания, чтобы вы могли цепочки последовательных операций, а не гнездо, и это облегчает обработку ошибок. – jfriend00

ответ

9

Как сказал jfriend00 выше, если вы собираетесь разрабатывать в node.js, тогда вам ДОЛЖНО стать комфортно писать асинхронный код.

"прикован обещания", вероятно, ваш лучший выбор:

ДОПОЛНЕНИЕ:

Этот учебник показывает обещание сцепления с Node.js SQL-запросы. Он также обсуждает, как вы можете использовать Q и/или Step, чтобы упростить код:

+0

Спасибо за примеры. Итак, для чего я пытаюсь сделать, если буду использовать обещания, как мне это сделать, чтобы не было необходимости вложенных запросов? Из этого последнего примера я начал реализовывать обещания в свой код, и это то, что я до сих пор «Q.ninvoke (db,« query »,« SELECT 1 as email_exists FROM users WHERE email = '+ db.escape (email)) .then (функция (строки) { , если (строки [0] .length> 0) { ошибки = { error_message: 'Адрес электронной почты берется', код_ошибки: 8 }; res.end (ошибка) } }) ', но мне еще не нужно вложить второй запрос в оператор else, который находится в then –

+0

Или я могу получить второй запрос в другом .then (function() {}); после первого первого? –

10

Вы могли бы просто использовать модуль для узла, который обеспечивает синхронные функции. Здесь вы найдете модуль, который предоставляет функции sync/async для работы с mysql.

https://github.com/Will-I4M/node-mysql-libmysqlclient

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

var config = require("./config.json") ; 
var mysql = require('mysql-libmysqlclient') ; 
var client = mysql.createConnectionSync(config.host, config.user, config.password, config.database) ; 

var query = "SELECT * FROM Users ;" ; 
var handle = client.querySync(query) ; 
var results = handle.fetchAllSync() ; 

console.log(JSON.stringify(results)) ; 
+0

Спасибо за это! Мне на самом деле нужен синхронный lib, чтобы связать цепочку редукторов. –

+0

Это должно быть принятым ответом –

+0

В качестве побочного примечания редуктор не является реальным редуктором (он, кроме прочего, теряет способность тестироваться), если он не является чистой функцией, которая последовательно возвращает значение, основанное на его аргументах. Никаких побочных эффектов, без получения данных отдельно от внешнего источника. –

1

Для большинства вещей, которые я коды в Node.js, мне нравится асинхронный код. Однако я полностью понимаю, что асинхронный код чрезвычайно и опасно несовместим с необходимостью писать и поддерживать бизнес-логику. Я использовал множество альтернативных методов. Модули, чтобы сделать вещи синхронными, по-прежнему оставляют вас с проблемами с областью данных, которые усложняют ситуацию. Обещания работали лучше для меня. Используя этот подход, я обнаружил, что практически пишу интерпретатор для нового языка поверх JavaScript. Я могу показаться абсурдным, но самый практичный и безопасный метод для меня оказался для использования модуля shelljs и клиента оболочки mysql.Это не большая производительность исполнения, но она значительно улучшает производительность разработчика и обеспечивает четкую и упорядоченную бизнес-логику, что крайне важно для бизнес-логики. Вот фрагмент кода, чтобы привести пример некоторых из того, что я создал:

var shell = require ('shelljs');

module.exports = { пользователя: '', пароль: '',

runSql:function(sql) { 
      var command = "echo '" + sql.replace(/'/g,"'\\''") + "' | mysql -u" + this.user.replace(/'/g,"'\\''") + " -p'" + this.password.replace(/'/g,"'\\''") + "'"; 
      var raw = shell.exec(command, {silent:true}).stdout; 
      //console.log('BASH -> MySQL YIELD: "' + raw + '"'); 
      if(raw.substr(0,5) === 'ERROR') { 
        console.log('ERROR Resulting from: ' + sql + '\n' + raw); 
        return []; 
      } 
      var rows = raw.split('\n'); 
      var names = []; 
      for(var r = 0; r < rows.length; r += 1) { 
        columns = rows[r].split('\t'); 

        // Capture column names 
        if(r === 0) { 
          names = columns; 
          continue; 
        } 

        // Reformat row into named valued 
        var fields = {}; 
        for(var c = 0; c < columns.length; c += 1) { 
          fields[names[c]] = columns[c]; 
        } 
        rows[r] = fields; 
      }; 

      // Eliminate extraneous first and last rows 
      rows.splice(0,1); 
      rows.splice(rows.length-1,1); 

      return rows; 
    }, 
+0

Позже я добавил что-то, чтобы проверить, возникла ли ошибка и сообщить об этом ... И я написал еще один метод, который использует этот метод для получения информации о дизайне таблицы, посредством команды MySQL «Описать tablename». Он отлично работает. После столь большой боли, пытаясь найти более технически правильные подходы, защищаемые людьми, которые не понимают нужды, я могу жить с тем, чтобы я это делал. в конечном счете, кому-то нужно написать модуль MySQL, который предлагает как синхронные, так и асинхронные методы. Лично мне очень хотелось бы, чтобы в JavaScript были инструкции «do together {..}» и «do in order {..}». – user1018645

Смежные вопросы