Node.js 在Express中的app.method回调之间传递变量
我试图从数据库中获取一个记录集,并将其存储在一个变量中,以便在呈现视图的后续回调中使用它。我尝试在req对象上创建一个变量,但在下一次回调中调用它时,它返回为未定义Node.js 在Express中的app.method回调之间传递变量,node.js,express,request,response,middleware,Node.js,Express,Request,Response,Middleware,我试图从数据库中获取一个记录集,并将其存储在一个变量中,以便在呈现视图的后续回调中使用它。我尝试在req对象上创建一个变量,但在下一次回调中调用它时,它返回为未定义 app.get( '/behaviorchart', authenticated, function(req, res, next) { sql.connect(dbconfig, function (err) { new sql.Request()
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上创建了一个属性,但我似乎也无法实现这一点
我在这里做错了什么?您下一次在这里打电话太早了:
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
});
});
},
x('something');
asyncFunction(args, function (err) {
y();
});
z();
但也要检查错误:
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
});
});
},
使现代化
关于为什么会发生这种情况的一些解释。当您运行这样的呼叫时:
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
});
});
},
x('something');
asyncFunction(args, function (err) {
y();
});
z();
实际情况是:
使用一个参数运行x
使用两个参数运行asyncFunction,其中一个恰好是函数,但尚未调用它-只是作为参数传递
在asyncFunction内部,可以安排一些异步操作,并保存匿名函数以供稍后调用,asyncFunction返回
不带参数运行z
稍后,异步操作完成,之前保存的匿名函数现在运行
匿名函数的运行方式为y
请参阅下面的答案,其中我更详细地解释了此类情况下的执行顺序和控制流:
您是否尝试过console.log记录集?sql是否向db插入了任何数据?是的,但它不是插入。存储过程是select语句。对于我自己的启发,在数据库完成查询之前,next是如何调用的?它位于回调中的sql.connect函数之后。它不是只有在sql.connect函数执行后才会运行吗?@cwanjt请参阅我更新的答案以获得更详细的解释。