这个Node.js中间件如何在没有参数的情况下工作?

时间:2017-02-05 18:29:40

标签: javascript node.js express

我正在使用其他人为expresspassport编写的函数,它定义了中间件(?),如下所示:

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');
    }
}

此功能在路由器中使用如下:

app.get('/page', isLoggedIn, function(req, res){
    // ...
});

我不明白的是,不应该使用参数reqres来调用函数吗?也许回调next不是必需的,因为它是app.get的下一个参数,但该函数如何访问reqres?我希望它被称为如下:

app.get('/page', isLoggedIn(req, res), function(req, res){
    // ...
});

如果不指定参数,它如何工作?

谢谢,

3 个答案:

答案 0 :(得分:3)

您传递给app.get()app.use()的所有功能都会自动调用req, res, next传递给他们。这就是app.get()app.use()的实施方式。

为了帮助您理解,这个例子:

app.get('/page', function(req, res){
    console.log(req.params.foo);
});

在功能上与此相同:

app.get('/page', myHandler);

function myHandler(req, res) {
    console.log(req.params.foo);
});

你不想做这样的事情:

app.get('/page', isLoggedIn(req, res), function(req, res){
    // ...
});

因为您尝试执行isLoggedIn(req, res)(当reqres尚未定义时),然后将其返回值传递给app.get()。这根本不是你想要的。您需要将函数引用传递给app.get(),它将在调用函数时提供参数。任何时候你把()放在Javascript中的函数之后,这意味着你现在想要执行它。但是,如果您只是传递函数的名称,那么这是一个函数引用,可以根据需要存储和调用。

此代码示例与此类似:

var result = isLoggedIn(req, res);

app.get('/page', result, function(req, res){
    // ...
});

除了这会导致错误,因为reqres在程序启动时没有定义,因此希望你可以看到你不想执行{{ 1}}现在。相反,您只想传递函数引用,以便Express稍后可以调用它。

答案 1 :(得分:1)

在此代码中

createFolder('file:///storage/emulated/0/', 'testFolder', ()=>{console.log('test');});

使用三个参数调用app.get('/page', isLoggedIn, function(req, res){ // ... }); 方法:

  1. 到页面的路线:app.get
  2. 中间件功能
  3. 请求处理程序功能
  4. 基本上,这段代码告诉快递框架,当收到/page路径的GET请求时,它应该调用两个函数:第一个是中间件函数,第二个是处理函数。

    这里需要注意的重要一点是,它是完成工作的框架。该框架将调用中间件函数,然后它将调用处理函数。

答案 2 :(得分:1)

  

我不明白的是,不应该使用参数req和res调用该函数吗?

get函数内的某处使用这些参数进行调用。假设这是简化的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 );
}

将函数传递给get有多种方法。例如,您传递匿名函数

get( function( res, req ) {
   return res + req;
}

您还可以传递在别处定义的命名函数

function isLoggedIn( res, req ) {
   return res + req;
}

get( isLoggedIn );

然而,这不是您所期望的:

get( isLoggedIn( res, req ) );

这里的问题是

isLoggedIn( res, req )

不再是声明功能。这是一个调用,此调用的结果取决于resreq。幸运的是,调用甚至可以产生一个数值,这意味着不再使用函数作为参数调用get,而是使用函数调用的结果

简而言之,要将命名函数传递给另一个函数,您不必指定其参数。假设允许的语法甚至没有意义,因为它与实际函数调用的语法(即调用的值)无法区分。

相关问题