在Express中的app.method回调之间传递变量

时间:2017-03-23 15:12:59

标签: node.js express request response middleware

我正在尝试从我的数据库中获取记录集并将其存储在变量中,以便我可以在呈现视图的后续回调中使用它。我已经尝试在req对象上创建一个变量,但是当我在下一个回调中调用它时它会返回为undefined。

app.get(
    '/behaviorchart',
    authenticated,
    function(req, res, next) {
        sql.connect(dbconfig, function (err) {
            new sql.Request()
                .input('TeacherID', sql.Int, req.user.UserID)
                .execute('dbo.GetTeacherStudentCards', function (err, recordsets, returnValue) {
                    req.studentCards = recordsets[0] // recordset without return value
                });
            sql.on('error', function (err) {
                // ... error handler 
            });
        });
        next();
    },
    function(req, res) {
        console.log(req.studentCards);
        res.render('behaviorchart.ejs', {
            user : req.user // gets user from session for ejs template
        }); 
    }
);

我读过一些人,特别是当他们在视图中使用变量时,会在res.locals上创建一个属性,但我似乎也无法使其工作。

我在这里做错了什么?

1 个答案:

答案 0 :(得分:1)

next()在这里打电话太快了:

function(req, res, next) {
    sql.connect(dbconfig, function (err) {
        new sql.Request()
            .input('TeacherID', sql.Int, req.user.UserID)
            .execute('dbo.GetTeacherStudentCards', function (err, recordsets, returnValue) {
                req.studentCards = recordsets[0] // recordset without return value
            });
        sql.on('error', function (err) {
            // ... error handler 
        });
    });
    // THIS IS CALLED BEFORE THE DATABASE QUERY FINISHES
    next();
},

尝试这样的事情:

function(req, res, next) {
    sql.connect(dbconfig, function (err) {
        new sql.Request()
            .input('TeacherID', sql.Int, req.user.UserID)
            .execute('dbo.GetTeacherStudentCards', function (err, recordsets, returnValue) {
                req.studentCards = recordsets[0] // recordset without return value
                // CALL NEXT HERE:
                next();
            });
        sql.on('error', function (err) {
            // ... error handler 
        });
    });
},

但也检查错误:

function(req, res, next) {
    sql.connect(dbconfig, function (err) {
        new sql.Request()
            .input('TeacherID', sql.Int, req.user.UserID)
            .execute('dbo.GetTeacherStudentCards', function (err, recordsets, returnValue) {
                // CHECK FOR ERRORS:
                if (err) {
                    return next(err);
                }
                req.studentCards = recordsets[0] // recordset without return value
                // CALL NEXT HERE:
                next();
            });
        sql.on('error', function (err) {
            // ... error handler 
        });
    });
},

更新

对其发生原因的一些解释。当您运行这样的呼叫时:

x('something');
asyncFunction(args, function (err) {
  y();
});
z();

实际发生的是:

  1. 使用一个参数运行x()
  2. 使用两个参数运行asyncFunction()(其中一个恰好是一个函数,但它尚未调用 - 只是作为参数传递)
  3. asyncFunction()内部可能会安排一些异步操作,并保存匿名函数以便稍后调用,asyncFunction()返回
  4. 不带参数运行z()
  5. 稍后异步操作完成,之前保存的匿名函数立即运行
  6. 匿名函数运行y()
  7. 请参阅此答案,我将更详细地解释执行和控制流程的顺序: