我的Express.js应用已投掷Cannot read property 'req' of undefined
。实质上,它会侦听GET
请求,获取content
查询,然后使用表进行回复。以下是提出问题的部分。
index.js
var panels = require('./modules/panels.js');
app.get('/panel', function (req, res) {
var user;
if (user = req.session.user) {
panels.getContents(req.query.content, user.innId, res.send);
} else {
res.sendStatus(401);
}
});
模块/ panels.js
exports.getContents = function(panelName, innId, callback) {
var response = "";
switch (panelName) {
case 'tenants':
con.query(queryString, queryParams, function(err, rows) {
if (err) {
handle(err);
} else {
if (rows.length == 0) {
var tenants = 0;
var debtors = 0;
} else {
var tenants = rows[0].tenants;
var debtors = rows[0].length;
}
response = convertToHTMLTable(rows);
}
callback(response); /*THE ERROR POINTS HERE */
});
break;
/* other cases here */
default:
response += "Invalid Request";
callback(response);
}
}
我做错了什么?我的猜测是我不想将res.send
作为回调传递。那么,我该如何解决呢?
答案 0 :(得分:24)
我也遇到了这个错误,在稍微咀嚼错误信息并盯着我的代码太长时间后,它点击了。
我(和上面的提问者)的代码看起来像这样:
handler(req, res) {
somethingAsync
.then(res.send) // <-- storing send() divorced from parent object "res"
}
问题是,当res.send稍后被调用时,它与动态范围脱节 - 这意味着在this
方法内调用send
,这通常会引用{ {1}},现在请参阅res
。显然,global
包含对res.send
的引用,给出错误消息。
等效方案:
this.req
或者,换句话说:
res = {
send: function() {
console.log(this.originalMessage.req);
},
originalMessage: { req: "hello SO" },
};
res.send();
// # "hello SO"
const x = {};
x.send = res.send;
x.send();
// # Uncaught TypeError: Cannot read property 'req' of undefined
两个解决方案:
new Promise(_ => _())
.then(_ => console.log(this.msg.req));
// # Uncaught (in promise) TypeError: Cannot read property 'req' of undefined
理论上更惯用的方法是
// ES6
handler(req, res) {
somethingAsync
.then(() => res.send()) // <- send is called as a method of res, preserving dynamic scope
}
动态范围的恶劣小问题,那一个。好像快递应该放弃那里的动态范围,或者至少抛出一个更好的错误......
答案 1 :(得分:2)
在 index.js
中试试panels.getContents(req.query.content, user.innId, res);
并进入panels.js
exports.getContents = function(panelName, innId, response) {
var response = "";
switch (panelName) {
case 'tenants':
con.query(queryString, queryParams, function(err, rows) {
if (err) {
handle(err);
} else {
if (rows.length == 0) {
var tenants = 0;
var debtors = 0;
} else {
var tenants = rows[0].tenants;
var debtors = rows[0].length;
}
response.send(convertToHTMLTable(rows));
}
});
break;
/* other cases here */
default:
error += "Invalid Request";
response.send(error)
}
}
答案 2 :(得分:1)
当您将res.send
作为参数传递给getContents
函数(panels.getContents(req.query.content, user.innId, res.send);
)时,它会传入一个新变量,您将其称为callback
。
因此,res.send
现在已从原来的/应该的lexical context
/ binding
剥离
在这种情况下为res
对象,并且看来res.send
使用req
在res
对象中使用this.req
属性。
您在这里所做的是无意地将函数this
的{{1}}的值更改为全局对象。
有两种方法可以解决此问题
send
//或
panels.getContents(req.query.content, user.innId, () => res.send);
在第二个解决方案中,您将函数panels.getContents(req.query.content, user.innId, res.send.bind(res));
绑定为始终将res.send
的任何值视为this
对象(res
)