何时使用next()并在Node.js中返回next()

Amo*_*rni 114 v8 connect node.js express

场景:考虑以下是节点Web应用程序的代码部分.

app.get('/users/:id?', function(req, res, next){
    var id = req.params.id;
    if (id) {
        // do something
    } else {
        next(); //or return next();
    }
});
Run Code Online (Sandbox Code Playgroud)

问题:我正在检查哪一个next()或只是return next().上面的示例代码对两者都完全相同,并且没有显示执行上的任何差异.

问题:有人可以对此有所了解,何时使用next()以及何时使用return next()和一些重要区别?

PJC*_*der 140

正如@Laurent Perrin的回答:

如果你不这样做,你就有可能在第二次触发回调,这通常会产生毁灭性的结果

如果你像这样编写中间件,我在这里给出一个例子:

app.use((req, res, next) => {
  console.log('This is a middleware')
  next()
  console.log('This is first-half middleware')
})

app.use((req, res, next) => {
  console.log('This is second middleware')
  next()
})

app.use((req, res, next) => {
  console.log('This is third middleware')
  next()
})
Run Code Online (Sandbox Code Playgroud)

你会发现控制台中的输出是:

This is a middleware
This is second middleware
This is third middleware
This is first-half middleware
Run Code Online (Sandbox Code Playgroud)

也就是说,它在所有中间件功能完成后运行next()下面的代码.

但是,如果您使用return next(),它将立即跳出回调,并且回调中的以下代码return next()将无法访问.

  • 作为一个"表达"的初学者,这个答案让我比其他答案更清楚.竖起大拇指! (22认同)
  • 在这种情况下,“res.redirect('/')”与“return res.redirect('/')”是否会出现类似的情况?也许最好总是在“res”语句前面写“return”,以避免在发送后设置标头时出现错误? (2认同)
  • 为什么要在next()之后写代码?我在中间件中完成任务后什么都不做,这不是很明显吗?@PJCHENder (2认同)

Lau*_*rin 117

有些人总是写的return next()是确保在触发回调后执行停止.

如果你不这样做,你就有可能在第二次触发回调,这通常会产生毁灭性的结果.你的代码很好,但我会把它重写为:

app.get('/users/:id?', function(req, res, next){
    var id = req.params.id;

    if(!id)
        return next();

    // do something
});
Run Code Online (Sandbox Code Playgroud)

它为我节省了缩进级别,当我稍后再次阅读代码时,我确信没有办法next被调用两次.

  • 在这种情况下,`res.redirect('/')`与`return res.redirect('/')`会有类似的情况吗?也许最好总是在res语句前写return,以避免发送头后设置头的错误? (2认同)

dri*_*hev 44

next()连接中间件的一部分.对于路由器流量回调如果返回从函数什么都不关心,所以return next()next(); return;基本相同.

如果您想要停止功能流,您可以使用next(err)如下所示

app.get('/user/:id?', 
    function(req, res, next) { 
        console.log('function one');
        if ( !req.params.id ) 
            next('No ID'); // This will return error
        else   
            next(); // This will continue to function 2
    },
    function(req, res) { 
        console.log('function two'); 
    }
);
Run Code Online (Sandbox Code Playgroud)

几乎next()用于扩展请求的中间件.

  • `next('No ID')`实际上发送了一个错误,这将打破流程. (7认同)
  • "所以返回next()和next(); return;基本相同." - 正是我需要阅读的内容.thx @drinchev (5认同)
  • 我观察到相反的情况(当触发错误时):next(error) 触发下一个中间件,但继续执行代码;return next(error) 只是将执行降级到下一个中​​间件。next(e) 和 return next(e) 不一样。 (2认同)

小智 5

next() 和 return next() 之间的区别非常简单,作为另一个编程原则。一些代码行解释如下:

    app.use((req, res, next) => {
       console.log('Calling first middleware');
       next();
       console.log('Calling after the next() function');
    });


    app.use((req, res, next) => {
       console.log('Calling second middleware');
       return next(); // It returns the function block immediately and call next() function so the return next(); and next(); return; are the same
       console.log('After calling return next()');
    });

Run Code Online (Sandbox Code Playgroud)

输出是

调用第一个中间件
在 next() 函数之后调用
调用第二个中间件