[英]How does this Node.js middleware work without arguments?
I'm using a function that someone else wrote for express
and passport
, which defines the middleware(?) as follows: 我正在使用其他人为
express
和passport
编写的函数,该函数按以下方式定义了中间件(?):
function isLoggedIn(req, res, next) {
if (req.isAuthenticated()){
return next();
}
else{
req.flash('error', 'You need to be logged in to access this page');
res.redirect('/login');
}
}
This function is used in the router as follows: 此功能在路由器中的用法如下:
app.get('/page', isLoggedIn, function(req, res){
// ...
});
What I don't understand is, shouldn't the function be called with parameters req
and res
? 我不明白的是,不应该使用参数
req
和res
调用该函数吗? Maybe the callback next
is not necessary since it's the next argument of app.get
, but how does the function access req
and res
? 也许
next
回调不是必需的,因为它是app.get
的下一个参数,但是该函数如何访问req
和res
? I would expect it to be called as follows: 我希望它被称为如下:
app.get('/page', isLoggedIn(req, res), function(req, res){
// ...
});
How does it work without specifying the arguments? 不指定参数如何工作?
Thanks, 谢谢,
Any functions that you pass to app.get()
or app.use()
are automatically called with req, res, next
passed to them. 传递给
app.get()
或app.use()
所有函数都会自动通过req, res, next
调用req, res, next
传递给它们。 That is how app.get()
and app.use()
are implemented. 这就是
app.get()
和app.use()
的实现方式。
To help you understand, this example: 为了帮助您理解,此示例:
app.get('/page', function(req, res){
console.log(req.params.foo);
});
is functionally the same as this: 在功能上与此相同:
app.get('/page', myHandler);
function myHandler(req, res) {
console.log(req.params.foo);
});
You do not want to do something like this: 您不想做这样的事情:
app.get('/page', isLoggedIn(req, res), function(req, res){
// ...
});
because here you're attempting to execute isLoggedIn(req, res)
(when req
and res
are not yet defined) and then pass it's returned value to app.get()
. 因为在这里您尝试执行
isLoggedIn(req, res)
(当尚未定义req
和res
时),然后将其返回值传递给app.get()
。 That is not what you want at all. 那根本不是你想要的。 You need to pass a function reference to
app.get()
and it will supply the parameters when it calls the function. 您需要将函数引用传递给
app.get()
,它将在调用函数时提供参数。 Any time you put ()
after a function in Javascript, that means you want to execute it NOW. 任何时候将
()
放在Javascript函数之后,都意味着您现在想执行它。 But, if you just pass the function's name, then that is a function reference which can be stored and called later as desired. 但是,如果仅传递函数名称,则该函数引用可以存储并在以后根据需要调用。
This code example is analogous to this: 此代码示例与此类似:
var result = isLoggedIn(req, res);
app.get('/page', result, function(req, res){
// ...
});
Besides the fact that this would cause an error because req
and res
are not defined at program start time when this would execute, hopefully you can see that you don't want to execute isLoggedIn()
now. 除了由于执行程序时未在程序启动时定义
req
和res
而导致错误的事实之外,希望您可以看到自己现在不想执行isLoggedIn()
。 Instead, you just want to pass a function reference so Express can call it later. 相反,您只想传递一个函数引用,以便Express稍后可以调用它。
In this code 在这段代码中
app.get('/page', isLoggedIn, function(req, res){
// ...
});
The app.get
method is being called with three arguments: 正在使用三个参数调用
app.get
方法:
/page
/page
Basically, this code is telling the express framework that when a GET
request is received for the /page
path, then it should call two functions: first, the middleware function and second the handler function. 基本上,这段代码告诉Express框架,当收到针对
/page
路径的GET
请求时,它应该调用两个函数:第一个是中间件函数,第二个是处理程序函数。
The important thing to note here is that it is the framework doing the work. 这里要注意的重要一点是它是完成工作的框架。 The framework is going to call the middleware function, then it's going to call the handler function.
该框架将调用中间件函数,然后将调用处理程序函数。
What I don't understand is, shouldn't the function be called with parameters req and res?
我不明白的是,是否应该不使用参数req和res调用该函数?
It will be called with these arguments, somewhere inside the get
function. 将在
get
函数内部的某个位置使用这些参数来调用它。 Suppose this is the simplified get
, implemented as 假设这是简化的
get
,实现为
// a super simple get that will expect a function
// and call the function with two arguments
function get( f ) {
var res = 1, req = 1;
f( res, req );
}
There are multiple ways of passing a function to get
. 有传递功能的多种方式
get
。 For example, you pass an anonymous function 例如,您传递一个匿名函数
get( function( res, req ) {
return res + req;
}
You can also pass a named function defined elsewhere 您还可以传递在其他地方定义的命名函数
function isLoggedIn( res, req ) {
return res + req;
}
get( isLoggedIn );
This however, is not what you'd expect: 但是,这不是您期望的:
get( isLoggedIn( res, req ) );
The problem here is that 这里的问题是
isLoggedIn( res, req )
is no longer a function declaration . 不再是函数声明 。 It is an invocation and the result of this invocation depends on what
res
and req
are. 这是一个调用 , 调用的结果取决于
res
和req
是什么。 With some luck, the invocation can even yield a number value, which means that get
is no longer invoked with function as an argument but with the result of function invocation. 运气好的话,该调用甚至可以产生一个数字值,这意味着
get
不再使用function作为参数来调用,而是使用function调用的结果来调用。
In short, to pass a named function to another function, you don't specify its arguments. 简而言之,要将命名函数传递给另一个函数,您无需指定其参数。 The supposed syntax that would allow this doesn't even make sense because it would be indistinguishable from a syntax of actual function invocation (ie the value of the call).
假定的允许这样做的语法甚至没有意义,因为它与实际函数调用的语法(即调用的值)没有区别。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.