在研究了一些中间件之后,我还有一个问题。
查看以下工作设置,它只是将do it函数附加到req对象,以便我们可以在任何路径中调用它,就像req.doit()
但 req,res,next 来自哪里? 我从未通过它们,我更加好奇它是如何工作的,因为匿名函数(2.)被另一个函数(1.)包围,我甚至可以传递参数。
MiddleWareTest.js:
var test = function(options){ //1.)
return function(req, res, next) { //2.)
req.doit = function() {
console.log('doit')
}
next();
}
}
module.exports = test;
app.js:
...
var myMiddleware = require('./MiddlewareTest.js')
app.use(myMiddleware())
...
欢迎任何加深我知识的建议:)
~Marc
答案 0 :(得分:6)
记住函数是JS中的对象,因此它们可以像任何其他对象一样传递和返回。
当您告诉express使用您的中间件时,您正在调用myMiddleWare
函数:
app.use(myMiddleWare());
此调用返回标记为\\2.
的anon函数。然后,Express.js会在处理请求时将其作为其中间件堆栈的一部分进行调用,并为其提供req
,res
和next
个参数。
通过检查arguments
对象,您始终可以看到哪些参数传递给函数。 (即console.log(arguments)
);
答案 1 :(得分:3)
当express通过中间件链时,参数(req,res,next)将传递给它。假设app.use是一个(更复杂的)版本:
app.use = function(middleware){
middlewareChain.push(middleware);
}
当请求到达时,express通过中间件链运行,从头到尾。调用第一个定义的中间件,使用当前req
,res
和next
,其中next
是链中的下一个中间件。
在链的末尾,next
只是一个空函数。希望到那时,您已经使用res
对象(如res.send
)做了一些事情。
(2)被匿名函数包围,因此您可以将调用中的选项传递给app.use
。例如,connect的cookieParser接受cookieSecret
。如果您正在开发没有选项的中间件,那么使用arity (req, res, next)
定义它并且跳过返回函数是可接受的(但不一致)。在这种情况下,您只需编写app.use(myMiddleware)
。