有一个非常简单的带路由器的Express路由器:
router.get('/users/:userId/roles/:roleId', function(req, res, next){
const roleId = req.params.roleId;
res.rest.resource = UserModel.findOne({ _id: req.params.userId}).exec().then(function(usr) {
console.log(req.params.roleId); // => undefined
console.log(roleId); // => okay here
const result = usr.roles.find( role => String(role._id) === String(roleId));
return result;
});
next();
});
因为它看到了承诺返回req.params.roleId
内的undefined
。这仅适用于next()
调用外部承诺then
的情况。
我可以使用asyncing和promises,并了解next()
将在then
中的处理程序之前调用。但req.params.roleId
发生了什么?它变异的原因和位置? next()
调用的中间件是否相同但变异req
?
注意:稍后调用的中间件使用res.rest.resource
来构建类似REST的响应。
答案 0 :(得分:5)
代码本身就是执行中的一种不确定性。
Something 会改变next()
处理程序中的角色ID,因为findOne()
最终会调度到then
处理程序需要一段时间,已经发生了。
如果不了解您的应用的更多详细信息,看起来这可能是正确的实现。
router.get('/users/:userId/roles/:roleId', function(req, res, next) {
const roleId = req.params.roleId;
UserModel.findOne({ _id: req.params.userId}).exec().then((usr) => {
const result = usr.roles.find(role => String(role._id) === String(roleId));
res.rest.resource = result;
next(); // <-- only dispatch to next after we find the resource result
});
});
var express = require('express');
var app = express();
app.use(function (req, res, next) {
var v = 0 | +new Date();
console.log("middleware 1 setting foos to ", v);
req.params.foo = v;
req.foo = v;
next();
});
app.use(function (req, res, next) {
console.log("middleware 2 reading foos and starting timer:", req.params.foo, req.foo);
setTimeout(function() {
console.log("middleware 2: foos are now", req.params.foo, req.foo);
}, 1000);
next();
});
app.get("/", function(req, res) {
res.send("params = " + JSON.stringify(req.params) + " and foo = " + req.foo);
});
app.listen(3000);
请求的输出是
middleware 1 setting foos to -902674369
middleware 2 reading foos and starting timer: undefined -902674369
middleware 2: foos are now undefined -902674369
middleware 1 setting foos to -902673113
middleware 2 reading foos and starting timer: undefined -902673113
middleware 2: foos are now undefined -902673113
并且浏览器输出为params = {} and foo = -902673113
,因此结果您不允许触摸req.params
,但您可以向{{1}添加任何其他属性对象,他们会一直很好。
这似乎是因为路径匹配层在每一步重写req
。