将数据从模型传递到节点js中的路由器
我试图从数据库传递一些数据给路由器,然后将数据传递给视图。将数据从模型传递到节点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我得到了一个未定义。我真的不明白为什么会出现这种情况。我还应该如何将数据传递到文件中。
所有帮助很乐意阅读:)谢谢。
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请求尚未完成),您最终会得到一个空表。有什么可以做的是:
- 您创建一个保存数据和
- 创建表
当你然后询问数据服务器(通过AJAX)的函数,你等待一个变量直到获得数据(完成回调),然后才开始创建表格:填充变量并调用函数以填充表格中的数据。
服务器端JavaScript与客户端相同。不要忘记这一点。
至于读者一点功课:走出回调地狱的方式是通过在承诺读了 - 一个模式/架构,减少缩进和节省大量的头痛:)
的(更新:卢卡斯的答案基本上讲同样的事情,像我一样)
(更新2:处理err
)
我建议实现路由文件的咨询,有的像这样:
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.query
的response
不能用于connection.query
而导致的。
错误的方式。如果你真的希望查询只运行一次,然后就重新使用已经查询数据,我认为你是在这样的事情之后你的模型:
...
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,只有使用的情况下,它仍然是不确定的回调,这会让你的路由器代码更convulated。
那么,如果我无法将结果保存到查询函数以外的变量,如何创建API?没有意义:O –
这是一个node.js异步的组合。这个问题可以解释:http://stackoverflow.com/questions/15635791/nodejs-mysql-connection-query-return-value-to-function-call –
我已经使用该回调方法。或者我不是? –