将数据从模型传递到节点js中的路由器

noa*_*dev 3 javascript module node.js express

我试图将一些数据从我的数据库传递到路由器,然后路由器将数据传递给视图.

我的型号代码:

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)
}
Run Code Online (Sandbox Code Playgroud)

现在到我的路线档案:

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;
Run Code Online (Sandbox Code Playgroud)

当我在console.log用户或Users.data时,我得到了未定义.我真的不明白为什么会这样.我怎么能沿着文件传递数据.

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

Lui*_*ell 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.
    }
Run Code Online (Sandbox Code Playgroud)

当您现在require将上述文件放在代码的另一个文件中时,上面的内容正在进行评估并立即保存(结果在该时间点未定义,因此在导出时也未定义).您的查询正在执行并写入result变量,但在那个时间点您不能再修改导出的变量 - 因为它是它自己的变量而不仅仅是对它的引用result.

你能做的是以下几点:

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

    module.exports = {
        getData: getData
    }
Run Code Online (Sandbox Code Playgroud)

然后在你的另一个文件中:

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

    Users.getData(function(err, result) {
        // TODO: Error handling.
        console.log(result);
    });
Run Code Online (Sandbox Code Playgroud)

这就是为什么用JavaScript最终在回调地狱中这么容易,因为它具有异步性质.

以上是完全相同的情况,就好像你想要从服务器通过AJAX获取一些数据,然后用它填充表格一样.当您获得数据之前开始创建表(因此AJAX请求尚未完成)时,您最终得到一个空表.可以做的是:

  1. 你创建一个保存数据的变量
  2. 一个创建表的函数

当你然后向服务器询问数据(通过AJAX)时,你要等到获得数据(完成回调),然后才开始创建表:填充变量并调用函数来填充表中的数据.

服务器端JavaScript与客户端相同.别忘了这个.

作为读者的一个小功课:摆脱回调地狱的方法是通过阅读承诺 - 一种减少缩进并节省大量头痛的模式/架构:)

(更新:卢卡斯的回答基本上和我说的一样)
(更新2:错误的处理方式err)