在Node js,Express中调用类时,返回值未定义

时间:2017-06-16 10:01:23

标签: javascript node.js express

我是节点js和表达框架的新手。我试图将值传递给javascript类来处理查询并调用数据库,我期待一个结果数组。这是我的代码:

这是我的路由器:

var express = require('express');
var router = express.Router();
var Database = require('../app/database.js');

var mysqlConnect = new Database()

router.get('/data-penjualan', (req, res) => {
    var start_date = req.query.start_date;
    var end_date = req.query.end_date;
    var city = req.query.city;
    // console.log(start_date);
    var result = mysqlConnect.generalData(start_date, end_date, city);
    console.log(result);
    res.render('header')
});

module.exports = router;

这是我的database.js app:

"use strict";
var mysql      = require('mysql');

module.exports = class Database {
  connect(query) {
    var connection = mysql.createConnection({
      host     : '###',
      user     : '###',
      password : '###',
      database : '###'
    });
    connection.connect();
    return connection.query(query, function(error, results, fields){
      if (error) {
        console.log('connection to database error');
      } else {
        var result = results;
        connection.end(function(err){
          if (err) {
            console.log('fail to end the connection');
          } else {
            console.log('connection has end after all query executed');
          }
        });
      }
      console.log(result);
      return result
    });
  }
  generalData(start_date, end_date, city) {
    if (city == null) {
      return null;
    } else {
      var query = `SELECT o.date_add, o.current_state , o.id_order, CONCAT(c.firstname , ' ' , c.lastname) AS fullname,
      REPLACE(TRIM(LOWER(SUBSTRING_INDEX(SUBSTRING_INDEX(s.name,',',2),",",-1))), 'kota administrasi ', '') AS city,
      a.phone_mobile, c.email, od.product_name, od.total_price_tax_excl FROM ps_orders AS o
      LEFT JOIN ps_order_detail AS od ON o.id_order = od.id_order
      LEFT JOIN ps_customer AS c ON o.id_customer = c.id_customer
      LEFT JOIN ps_address AS a ON o.id_address_delivery = a.id_address
      LEFT JOIN ps_state AS s ON a.id_state = s.id_state
      WHERE o.date_add BETWEEN '${start_date}' AND '${end_date}'
      AND o.current_state IN (2,4,5)
      HAVING city REGEXP '${city}' ;`;
    }
    // console.log(query);
    this.connect(query);
  }
}

在console.log上(结果);在database.js上我可以记录结果,但是在console.log上(结果);在我的路由器上返回UNDEFINED的值。我怎样才能解决这个问题 ?感谢

1 个答案:

答案 0 :(得分:0)

您应该阅读一些关于JS(和NodeJS)事件驱动的性质。

在您的代码中:

connect(query) { // (1)
  var connection = mysql.createConnection({
    host     : '###',
    user     : '###',
    password : '###',
    database : '###'
  });
  connection.connect();
  return connection.query(query, function(error, results, fields){ // (2)
    if (error) {
      console.log('connection to database error');
    } else {
      var result = results;
      connection.end(function(err){
        if (err) {
          console.log('fail to end the connection');
        } else {
          console.log('connection has end after all query executed');
        }
      });
    }
    console.log(result);
    return result // (3) !!! This return is not for (1), it is for (2)
  });
}

return语句(3)使传递给function(error, results, fields){的回调(connection.query())的返回值为result。但是由于JS函数的异步性,connect(query)已经返回了它的返回值,它是connection.query()在调用时返回的东西 - connection.query()立即返回,它不等待回调到完整。

如果您想继续使用回调,那么您的代码应如下所示:

"use strict";
var mysql      = require('mysql');

module.exports = class Database {
  connect(query, callback) {
    var connection = mysql.createConnection({
      host     : '###',
      user     : '###',
      password : '###',
      database : '###'
    });
    connection.connect();
    return connection.query(query, function(error, results, fields){
      if (error) {
        console.log('connection to database error');
        return callback(error); // report error, return to stop processing
      } else {
        var result = results;
        connection.end(function(err){
          if (err) {
            console.log('fail to end the connection');
          } else {
            console.log('connection has end after all query executed');
          }
        });
      }
      console.log(result);
      // return result no need for this
      return callback(null, result);
    });
  }
  generalData(start_date, end_date, city, callback) {
    if (city == null) {
      return callback(null, null); // functions should be consistent in a way they return data: either sync return or async callback
    } else {
      var query = `SELECT o.date_add, o.current_state , o.id_order, CONCAT(c.firstname , ' ' , c.lastname) AS fullname,
      REPLACE(TRIM(LOWER(SUBSTRING_INDEX(SUBSTRING_INDEX(s.name,',',2),",",-1))), 'kota administrasi ', '') AS city,
      a.phone_mobile, c.email, od.product_name, od.total_price_tax_excl FROM ps_orders AS o
      LEFT JOIN ps_order_detail AS od ON o.id_order = od.id_order
      LEFT JOIN ps_customer AS c ON o.id_customer = c.id_customer
      LEFT JOIN ps_address AS a ON o.id_address_delivery = a.id_address
      LEFT JOIN ps_state AS s ON a.id_state = s.id_state
      WHERE o.date_add BETWEEN '${start_date}' AND '${end_date}'
      AND o.current_state IN (2,4,5)
      HAVING city REGEXP '${city}' ;`;
    }
    // console.log(query);
    this.connect(query, callback); // simply pass provided callback, your this.connect() will call it with something
  }
}

否则你可以使用asise / await和Promises https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/await