Javascript 在节点js、Express中调用类时返回值未定义

Javascript 在节点js、Express中调用类时返回值未定义,javascript,node.js,express,Javascript,Node.js,Express,我对NodeJS和express框架有点陌生。我试图将值传递给javascript类以处理查询并调用数据库,我希望得到一个结果数组。这是我的密码: 这是我的路由器: var express = require('express'); var router = express.Router(); var Database = require('../app/database.js'); var mysqlConnect = new Database() router.get('/data-pe

我对NodeJS和express框架有点陌生。我试图将值传递给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应用程序:

"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(result)上;在我的路由器上,返回值未定义。我怎样才能解决这个问题?谢谢

您应该阅读一些关于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)将回调(
函数(错误、结果、字段){
)的返回值传递给
connection.query()
成为
result
。但由于JS函数
connect(查询)的异步性质
已经返回了它的返回值,并且它是
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
  }
}

否则,您可以在
generalData
函数中使用async/wait with promissions

,执行查询但从不返回结果,因此该函数的计算结果将始终为
undefined
。您好,感谢您的回复。由于我对这一点不熟悉,假设我正在遵循您的解决方案,如何将值传递给路由器?
mysqlConnect.generalData(开始日期,结束日期,城市,(错误,结果)=>{console.log(结果);res.render('header');});
如文档(,响应方法)中所述:响应对象(res)上的方法在下表中,您可以向客户端发送响应,并终止请求响应周期。如果路由处理程序没有调用这些方法,则客户端请求将挂起。这意味着您可以在回调中调用任何
res
方法。您好,谢谢您的回答,现在问题已经解决了。谢谢您的时间