如何有效地使用事件驱动的回调与mySQL查询?

时间:2018-03-17 22:18:57

标签: node.js express

我遇到了异步调用的一些问题,但在理解了Node中的事件驱动函数之后,我有以下代码。它基本上做了2个SQL查询。首先检查表中是否有现有的电话号码。如果有,没有任何反应。如果没有,则运行第二个查询以向表中添加新值。

目前它是事件驱动的,但是..我如何重新设计它以便外部函数查询是一个单独的函数,甚至可以用作其他地方代码的验证检查? (基本上把它变成通用的辅助函数)?

router.post('/', function(req, res){
    var mysql = req.app.get('mysql');

    //values for 1st query - initial check
    var customerCheck = "SELECT phone_number FROM customer WHERE phone_number=?";
    var phoneNumberCheck = [req.body.phone_number];

    //values for after 1st query validation passes
    var sql = "INSERT INTO customer (name, phone_number, points, is_activated) VALUES (?,?,?,?)";
    var inserts = [req.body.name, req.body.phone_number, 0, true];

    mysql.pool.query(customerCheck, phoneNumberCheck, function(error, results, fields){
        if(error){
            console.log("Failed to verify!");
            res.write(JSON.stringify(error));
            res.end();
        }else{
            console.log(results);
            if(results.length){
                console.log("phone number exists, not adding.");
                res.redirect('/view_customers');
            }else{
                mysql.pool.query(sql,inserts,function(error, results, fields){
                    if(error){
                        console.log("Failed to insert customer to DB!");
                        res.write(JSON.stringify(error));
                        res.end();
                    }else{
                        res.redirect('/view_customers');
                    }
                });

            }
        }
    });
});

2 个答案:

答案 0 :(得分:1)

这是一种更有条理的方式,当然可以改进,但我把它留给你。

我添加了一个客户类,您可以在其中拥有checkinsert个功能,现在您可以单独使用它们。

我将数据库查询包装在一个承诺中,以避免回调地狱(Learn how to avoid it here

最后,路由器功能变得非常简单易读。

<强> customer.js

class Customer {

    constructor(mysql) {
        this.mysql = mysql;
    }

    async check(number) {

        const statement = 'SELECT phone_number FROM customer WHERE phone_number=?';

        const results = await this.query(statement, [number]);

        // If there is a customer with that phone number
        // we return true, false otherwise.
        return results.length;

    }

    insert(name, number) {
        const statement = 'INSERT INTO customer (name, phone_number, points, is_activated) VALUES (?,?,?,?)';

        return this.query(statement, [name, number, 0, true]);

    }

    query(query, placeholders) {
        // We wrap the query in a promise
        // So we can take advantage of async/await in the other functions
        // To make the code easier to read avoiding callback hell
        return new Promise((resolve, reject) => {

            this.mysql.pool.query(query, placeholders, (error, results) => {

                if(error)
                    return reject(error);

                resolve(results);

            });
        });
    }

}

module.exports = Customer;

<强>路由器

const Customer = require('./customer');

// ... rest of your code

router.post('/', async(req, res) => {

    const customer = new Customer(req.app.get('mysql'));

    try {

        // We check whether the client exists or not
        const check = await customer.check(req.body.phone_number);

        if(!check) // We insert the customer if it doesn't exists
            await customer.insert(req.body.name, req.body.phone_number);

        // After successful insert or if the customer already exists
        // we redirect to /view_customers
        res.redirect('/view_customers');

    } catch(error) {

        // Probably a database error
        console.log('Oops');
        res.write(JSON.stringify(error));
        res.end();
    }

});

答案 1 :(得分:0)

你可以为它编写一个函数来返回一个简化事物的承诺,例如:

function checkFn(mysql, v) {
  return new Promise((resolve, reject) => {
    var customerCheck = "SELECT phone_number FROM customer WHERE phone_number=?";
    var phoneNumberCheck = [v];
    mysql.pool.query(customerCheck, phoneNumberCheck, function(error, results, fields){
      if(error){
          console.log("Failed to verify!");
          reject();  // reject promise
      }else{
          console.log(results);
          if(results.length){
              console.log("phone number exists, not adding.");
              resolve(true);   // resolve promise with true
          }else{
              resolve(false);   // resolve promise with false
          }
      }
    })
  })
}

然后您可以将它与async / await

一起使用
router.post('/', async function(req, res){    // notice: async
  try {
    let numberExist = await checkFn(req.app.get('mysql'), req.body.phone_number)
    if (numberExist) {
       // do something if number exists
    } else {
       // do something if number doesn't exist
    }
  }
  catch (e) {
    // do something if error
  }

阅读:Async function