从数据库返回数据到控制器

Posted

技术标签:

【中文标题】从数据库返回数据到控制器【英文标题】:returning data from db up to controller 【发布时间】:2019-11-21 13:09:34 【问题描述】:

我正在使用 MVC 架构在 Express 中构建一个新的 API,但我无法从 db 访问文件中获取数据以返回到控制器文件。

我开始尝试使用回调函数,然后切换到 Promise,但我很确定我错过了导致我的问题的范围的一些内容。我一遍又一遍地绞尽脑汁和谷歌,为此工作了几天,但无济于事。

//这是控制器文件代码

let bodyparser = require('body-parser');
const dbUtilities = require('../db/db.js');

let controller = 
  retrieveTables: function(req, res)
    database = req.params.database;
    query = ["SHOW TABLES FROM " +database +";"];
    connectDb(query, database, function(results)
      res.render('dashboard', data: results);
      console.log('results from controller' + results);
    );
  ,

//这是我处理从mysql检索数据的db.js文件

var mysql = require('mysql');

//generalized utility db functions
//function to open a db connection

//opening the connection to the database
connectDb = function(query, database)  
resultData = [];
  var connectionPromise = dbConnect(database);
    connectionPromise.then(function(connection)
      for(var i = 0; i < query.length; i++)
        var queryPromise = buildQuery(connection, query[i]);
        queryPromise.then(function(result)
          console.log('QUERY' + i + ': ' + query[i]);
          console.log(result);
          resultData.push(result);
          if(resultData.length == query.length)
            dbDisconnect(connection);
            return(resultData);
          
        )
      
    );

//opening the db connection
function dbConnect(database)
  return new Promise(function(resolve, reject)
    var connection = mysql.createConnection(
      host : 'localhost',
      user : 'rcg',
      password: '8693ViaMallorca',
      database: database
    );

    connection.connect(function(err) 
      if(err) 
        console.error('error connecting: ' + err.stack);
        reject(error);
      
      else
        console.log('connected as id ' + connection.threadID);
        resolve(connection);
      
    );
  );


//building the query promise function
function buildQuery(connection, query)
  return new Promise(function(resolve, reject)
    connection.query(query, function(error, results, fields)
      if(error)
        console.error('error retrieving the query');
        console.log(query);
        reject(error);
      
      else
        resolve(results);
      ;
    );
  );


//closing the connection to the database
function dbDisconnect(connection)
  connection.end(function(err) 
    if(err) 
      console.error('error terminating connection');
      return(error);
    
    else
      return(console.log('connection successfully terminated'));
    
  );



module.exports = connectDb;

【问题讨论】:

欢迎来到 SO!您可以编辑您的问题以添加特定的错误消息吗?或者一个想法可能不会从控制台输出失败? 我还建议您看看像 Knex 这样的库,而不是自己动手。 来自控制器文件的 res.render 调用始终未定义。数据似乎永远不会回到控制器文件中。 我认为问题不在于 SQL,因为我可以从 db.js 文件发送结果并且它们正确显示。这是让数据返回到原始调用函数的问题。 它给出了一组对象,这些对象对应于数据库中的一组表。我可以控制台记录数据并查看其正确性,但如果我尝试控制台记录控制器文件中的数据,我什么也得不到。 【参考方案1】:

这不起作用的原因是因为您只在内部回调中返回。您也需要在外部回调中返回。数据没有返回到被调用者(例如:控制器)的返回路径。既然你提到了 async/await,我重写了它以反映现代 async/await 语法。

const connectDb = async function(query, database)  
  resultArray = [];
  const connection = await dbConnect(database);

  for(let i = 0; i < query.length; i++) 
    const result = await buildQuery(connection, query[i]);
    console.log(result);
    resultArray.push(result);
  
  return resultArray;
);

我重写了它以使用与下面相同的 async/await 语法。您可以使用当前正在使用的回调语法,但如果不更改它,您将无法使用下面的代码。我认为 async/await 语法更直接。将res.render 作为函数中的最后一件事也很重要(因为它表示您已完成处理请求的回调)。

const controller = 
  retrieveTables: async function(req, res) 
    const database = req.params.database;
    const query = ["SHOW TABLES FROM " + database + ";"];

    const results = await connectDb(query, database);
    console.log('results from controller', results);
    res.render('dashboard', data: results);
  

【讨论】:

以上是关于从数据库返回数据到控制器的主要内容,如果未能解决你的问题,请参考以下文章

将多个参数从控制器传递到工厂服务进行 REST 调用并返回(可选)数据

尝试将数据从 db 返回到控制器并出现“如果您正在使用 DataContractSerializer,请考虑使用 DataContractResolver”错误

如何获取数据以从 NSURLSessionDataTask 返回

数据服务器到 iPhone 并返回

将范围变量从控制器绑定到指令而不使用$ watch

CodeIgniter 从控制器返回数据