在Node.js Express中 - 使用app.use functions-
为什么我不必这样做:
app.use(function(req,res,next){
//do something here
next(req,res);
});
通常我只是这样做而且有效
app.use(function(req,res,next){
//do something here
next();
});
答案 0 :(得分:5)
next()
已经知道当前正在执行的请求的req
和res
,因此您只需直接调用它即可。它是为此请求创建的唯一函数。它还会跟踪您当前在中间件堆栈中的位置,以便调用next()
执行链中的下一个中间件。
如果查看express source code for the router,您实际上可以看到本地定义的next()
函数,并且可以看到它如何访问包含req
的一堆闭包定义变量, res
和它用于推进中间件堆栈和一堆其他变量的索引计数器。因此,它已经可以访问启动下一个中间件调用所需的所有内容,因此没有理由将其传递给那些东西。
仅供参考,使用开源的一个好处是你可以随时自己查看代码,看看代码是什么。
调用next()
时,您有以下几种选择:
您可以将其作为next()
调用,这只会调用堆栈中的下一个中间件处理程序。
您可以将其作为next('route')
调用,它将跳转到下一个路由处理程序。
您可以传递错误next(err)
并停止所有进一步的中间件或路由器处理,错误处理程序除外。
详细信息请记录在此处:http://expressjs.com/guide/error-handling.html。
这是该页面的注释:
next()
和next(err)
类似于Promise.resolve()
和Promise.reject()
。它们允许您发信号表示这一点 当前处理程序已完成并处于什么状态。next(err)
将全部跳过 链中剩余的处理程序除了设置的那些处理程序 处理错误,如下一节所述。
答案 1 :(得分:1)
使用next
接受可选的Error
对象。如果你没有通过任何东西,它会假定你已准备好继续下一个中间件或你真正的挂载处理程序。 否则,如果您传递Error
对象的实例,您将绕过已挂载的处理程序(和顺序中间件)并直接转到错误处理程序。
app.use(function (req, res, next) {
if (!req.user || !req.user.isAuthorized) next(Error('not allowed'))
else next()
})
app.get('/:user', function (req, res, next) {
res.render('users/index', { user: req.user })
})
app.use(function (err, req, res, next) {
console.log(err.message) // not allowed
res.render('500', err)
})
答案 2 :(得分:0)
我试图通过查看jfriend00提供的源代码来了解内部工作原理,但不想浪费太多时间试图隔离处理回调的特定部分。
所以我尝试了自己的: jsfiddle
function MW(req, res){
var req1 = req, res1 = res;
Array.prototype.shift.apply(arguments);
Array.prototype.shift.apply(arguments);
var MWs = arguments;
console.log(MWs, req1, res1);
function handle(index){
if(index ===MWs.length-1){
return ()=>{MWs[index](req1, res1, ()=>{})};
}
return ()=>{MWs[index](req1, res1, handle(index+1))};
}
var next = handle(0);
next();
}
基本上,它使用递归来构建回调链。
然后您可以将其用作Express use/get/post/put/...
:
MW(req, res,
(req, res, next)=>{
console.log("first");
req.locals = {
token : 'ok'
};
res.canSend =false;
next();
},
(req, res, next)=>{
console.log("second");
console.log(req.locals.token, res.canSend);
next();
}
);