为什么在快速路由中调用next()是可选的?

ank*_*nfo 2 callback node.js express node-async

在Nodejs/Express的许多示例中,我看到在成功的情况下调用next()是可选的.

exports.postLogin = (req, res, next) => {
  passport.authenticate('local', (err, user, info) => {
    if (err) {
        return next(err);
    }
    req.logIn(user, (err) => {
      if (err) { return next(err); }
      req.flash('success', { msg: 'Success! You are logged in.' });
      res.redirect(req.session.returnTo || '/');
    });
  })(req, res, next);
};
Run Code Online (Sandbox Code Playgroud)

此外,很容易跳过nextargs中的回调:

exports.postLogin = (req, res) => {
  res.render('some-template', locals);
}
Run Code Online (Sandbox Code Playgroud)

如果我将它与asynclib或典型的Javascript异步模型进行比较,则缺少的回调将不会提供数据或停止进程.

这是什么express做时要小心控制流的next不叫?

Frx*_*rem 9

next正如您可能认为的那样,Express中间件链中的真正回调实际上并非如此res.end().处理的任何请求必须在某个时刻调用此函数(直接或间接)来表示已处理该请求.

next()您使用middeware 调用时,您将承担res.end()在中间件链中进一步调用中间件的责任.如果链中的最后一个中间件调用next(),则Express知道没有中间件已经或将要处理该请求,因此将生成"404 Not Found"页面.


此外,next(err)使用单个参数调用的err方式不同,因为它告诉Express发生错误并且它应该立即停止处理请求.

  • 查看`express`代码,`res.end()`实际上是[http.ServerResponse.end](https://nodejs.org/api/http.html#http_request_end_data_encoding_callback).所有其他方法,如res.render(),sendFile(),send()内部调用res.end(),**true回调**! (4认同)

rob*_*lep 5

next用于将请求传递给其他(可能的)处理程序。如果您正在编写不想处理请求的中间件或(不太可能)路由处理程序,您可以调用next并让 Express 来解决它。也许有其他中间件或其他路由处理程序可以处理它。

如果您的代码确实处理了该请求,这意味着它发回了响应,则您不应调用next. Express 并不关心这一点:在内部,中间件和路由处理程序存储在一个数组中,并且 Express 检查每个项目以查看它是否可以处理该请求。它传递该next函数,以便可以告诉它尝试下一个匹配的处理程序。但这是可选的。

它还用于将错误传递给 Express,因此它可以将它们沿着全局错误处理程序传递。next(err)这就是当你看到被呼叫时会发生的情况。