2015-10-07 40 views
2

我试图从数据库传递一些数据给路由器,然后将数据传递给视图。将数据从模型传递到节点js中的路由器

我的模型代码:

var mysql = require('mysql'); 

var connection = mysql.createConnection({ 
    host:  'localhost', 
    user:  'root', 
    password: '', 
    database: 'test' 
}); 

var result; // empty var which should later be filled with the querys result 

connection.connect(); 

var query = connection.query('SELECT * FROM users', function(err, res, fields) { 
    if (err) throw err; 

    result = res; // overwrite result with the querys result 
    console.log(res); // This prints out everything I need 
}); 


module.exports = { 
    data: result // should contain the query result (= 2 objects in this case) 
} 

现在我的路由文件:

var express = require('express'); 
var router = express.Router(); 

var Users = require('../models/users'); 

console.log(Users.data); 
/* GET home page. */ 
router.get('/users', function(req, res) { 
    res.render('api', { data: Users.data, title: "Test API Output" }); 
}); 

module.exports = router; 

当我CONSOLE.LOG用户或Users.data我得到了一个未定义。我真的不明白为什么会出现这种情况。我还应该如何将数据传递到文件中。

所有帮助很乐意阅读:)谢谢。

回答

5

module.exports正在评估第二个你require和变量是而不是通过引用在这种情况下通过。

这也就意味着你的代码如下:

var result; // result is "undefined" because it does not contain a value here 
    // You are doing your DB queries here... 
    module.exports = { 
     data: result // ...and because the query has not finished here yet, result 
         // is still undefined. 
     // This is also a good example of a so called "race condition", because there is a 
     // slight (improbable) chance that the query might have already finished. 
     // Hence, it could happen that sometimes result is already filled. 
    } 

现在,当您require在你的代码的另一个文件上面的文件,上面正在评估和保存直线距离(结果是不确定的在那个时间点,因此它在出口时也是不确定的)。 正在执行查询并写进result变量,但在那个时间点,你不能再修改导出的变量 - 因为它是它自己的变量,而不是仅仅是一个以result参考)。

你可以做的是:

function getData(callback) { 
     connection.query('SELECT * FROM users', function(err, res, fields) { 
      callback(err, res); 
     }); 
    } 

    module.exports = { 
     getData: getData 
    } 

,然后在其他的文件:

var Users = require('../models/users'); 

    Users.getData(function(err, result) { 
     // TODO: Error handling. 
     console.log(result); 
    }); 

这正是为什么它是如此容易使用JavaScript在回调地狱结束了,因为它是异步的。

以上是完全相同的情况下,如果你,F.E.,想从服务器获得通过AJAX的一些数据,然后填写表格吧。当您在之前开始创建表时,您有数据(因此AJAX请求尚未完成),您最终会得到一个空表。有什么可以做的是:

  1. 您创建一个保存数据和
  2. 创建表

当你然后询问数据服务器(通过AJAX)的函数,你等待一个变量直到获得数据(完成回调),然后才开始创建表格:填充变量并调用函数以填充表格中的数据。

服务器端JavaScript与客户端相同。不要忘记这一点。

至于读者一点功课:走出回调地狱的方式是通过在承诺读了 - 一个模式/架构,减少缩进和节省大量的头痛:)

的(更新:卢卡斯的答案基本上讲同样的事情,像我一样)
(更新2:处理err

1

我建议实现路由文件的咨询,有的像这样:

var express = require('express'); 
    var router = express.Router(); 

    var Users = require('../models/users'); 

    var mysql = require('mysql'); 

    var connection = mysql.createConnection({ 
     host:  'localhost', 
     user:  'root', 
     password: '', 
     database: 'test' 
    }); 

    var result; // empty var which should later be filled with the querys result 

connection.connect(); 

    /* GET home page. */ 
    router.get('/users', function(req, res) {   

     var query = connection.query('SELECT * FROM users', function(err, res, fields) { 
      if (err) throw err; 

      result = res; // overwrite result with the querys result 
      res.render('api', { data: res.data, title: "Test API Output" }); 
     }); 
    }); 

    module.exports = router; 

但你可以配置在另一个文件与数据库的连接,在libs/mysql_connect.js

undefined是由于connection.queryresponse不能用于connection.query而导致的。

+0

那么,如果我无法将结果保存到查询函数以外的变量,如何创建API?没有意义:O –

+0

这是一个node.js异步的组合。这个问题可以解释:http://stackoverflow.com/questions/15635791/nodejs-mysql-connection-query-return-value-to-function-call –

+0

我已经使用该回调方法。或者我不是? –

1

错误的方式。如果你真的希望查询只运行一次,然后就重新使用已经查询数据,我认为你是在这样的事情之后你的模型:

... 
var data; 
var mymodel = {}; 
... 
mymodel.getData = function(callback) { 
    if(data) { 
     callback(data); 
    } else { 
     db.query('select * from users', function(err,res,fields) { 
      // error checking and such 
      data = res; 
      callback(data); 
     }); 
    } 
} 
module.exports = mymodel 

在你的路由器,你再使用这样的:

... 
router.get('/users', function(req, res) { 
    Users.getData(function(mydata) { 
     res.render('api', { data: mydata, title: "Test API Output" }); 
    }); 
}); 

第一次调用的getData,你会得到一个新的结果,并在后续调用你获得缓存的结果。

虽然你可能暴露数据直接为MyModel,只有使用的情况下,它仍然是不确定的回调,这会让你的路由器代码更convul​​ated。

相关问题