MySQL,Node.js顺序操作 - 我该怎么做?

时间:2016-08-19 19:25:37

标签: javascript mysql node.js

我有以下代码:

function query1() {

var defered = Q.defer();

console.log("In query1");

var connection = mysql.createConnection({
    host: '........',
    user: 'm...c....a.....i',
    password: '......Z....9...K',
    database: '.....ol'
});

connection.connect(function(err) {
    if (!err) {
        console.log("Database is connected ...");
    } else {
        console.log("Error connecting database ...");
    }
});

sql = '' +
    'select c.ID as CENA_ID, ' +
    '      c.I_KEY as CENA_NUMERO, ' +
    '      c.NM_CENA as CENA_NOME, ' +
    '      b.DS_MAC as MAC_BOX, ' +
    '      v.DS_CLIENTID as ALEXA_ID, ' +
    '    v.FK_ID_GRUPO as GRUPO_ID ' +
    '  from TB_DISPOSITIVOS_VOZ v ' +
    '      inner join TB_GRUPOS g ' +
    '      on g.ID = v.FK_ID_GRUPO ' +
    '      inner join TB_CENAS c ' +
    '      on g.ID = c.FK_ID_GRUPO ' +
    '      inner join TB_CENTRAIS b ' +
    '      on g.ID = b.FK_ID_GRUPO ' +
    'where v.DS_CLIENTID = "' + userId + '" ' +
    'and lower(c.NM_CENA) like "%' + sceneName.toLowerCase() + '%"';


console.log("Created query");

try{

    connection.query(sql, function(erro, rows, fields) {

        if (!erro) {

            console.log("Executed query verifying the userId");

            contador = 0;

            if (rows.length > 0) {

                cena_id = rows[0].CENA_ID;
                cena_numero = rows[0].CENA_NUMERO;
                cena_nome = rows[0].CENA_NOME;
                alexa_id = rows[0].ALEXA_ID;
                grupo_id = rows[0].GRUPO_ID;
                mac_box = rows[0].MAC_BOX;

                contador = contador + 1;

            }

            console.log("contador: " + contador);

        } else {
            console.log("Error - getting the Alexa register in database" + erro);
            context.fail("Error - getting the Alexa register in database" + erro);
        }

    });


}catch (ex){
    console.log("exception: " + ex);
}

}

此代码也是如此:

Q.all([query1()]).then(function(results) {

        console.log("Q.all log function");

        if (contador > 0) {

            console.log("contador > 0");

            var client = mqtt.connect('mqtt://.............com');
            console.log("connected to MQTT broker");

            var buffer = [26,
                0,0,0,0,555,645,0,0,0,0,0,
                0,5555,2,Math.floor((Math.random() * 200) + 1),
                0,0,0,333,13,4,0,1,0,
                cena_numero
            ];

            console.log("Created buffer");

            client.on('connect', function() {

                client.publish('n/c/' + mac_box + '/app', buffer);

                console.log("sent MQTT");

            });

            speechOutput = "Command " + sceneName + " executed successfully";
            repromptText = "";
            console.log("Process executed successfully")

        } else {

            console.log("contador <= 0");

            speechOutput = "This command was not found!";
            repromptText = "";

        }

    }, function (reason) {

        console.log("reason: " + reason);

    });

如果第一个query1()正确执行,我该如何执行第二个代码?因为在函数query1()中我有一个MySQL查询,我只能在查询结果之后继续处理。

任何人都可以帮助我?

非常感谢!

2 个答案:

答案 0 :(得分:1)

你缺少关于Node.js中的回调和异步行为的一些关键概念。你正在使用“Q”库(顺便说一句,我建议尝试使用bluebird)来处理promises,但你的“query1”函数不会返回一个promise。这就是query1执行但你的“Q.all log function”将在query1完成之前执行的原因。

你可以像这样构建你的代码(我会用蓝鸟给出一个例子,因为我对它更熟悉):

var Promise = require('bluebird');

var _connection;

function query1() {
  return new Promise(resolve, reject) {
    //open your connection
    connection.open(function (err, connection) {
      if (err) return reject(err);

      _connection = connection;
      //do your query
      _connection.query(sql, [params], function (err, data) {
        if (err) return reject(err);
        else resolve(data);
      });
    });
  });
}

function query2(data) {
  return new Promise(resolve, reject) {
    //do your query, using data passed in from query1
    _connection.query(sql, [params], function (err, data) {
      if (err) return reject(err);
      else resolve(data);
    });
  });
}


query1
  .then(function (data) { query2(data); })
  .catch(function (err) {
    console.log('error:', err);
  });

另外,仅仅是FYI,连接这样的SQL字符串是一个禁忌,它会打开你的SQL注入攻击:

like "%' + sceneName.toLowerCase() + '%"

相反,请使用like "%?%"并使用connection.query(sql, [sceneName], function(err, data) {})调用您的SQL。希望这会有所帮助。

答案 1 :(得分:0)

我用async这个包解决了我的问题:

var async = require('async');

async.series([
            function(callback) {

                //action 1...

            },
            function(callback){

                //action 2...
            }
        ], function(err) { 
            if (err) {
                speechOutput = "Scene not found!";
                repromptText = "Please try again.";
            }
            console.log("Before speechOutput");
            callback(sessionAttributes,
                    buildSpeechletResponse(cardTitle, speechOutput, repromptText, shouldEndSession));   
        });