一尘不染

尝试在express.js中理解'next / next()'时遇到困难

node.js

这是一个例子:

// Configuration
app.configure(function(){
  app.set('views', __dirname + '/views');
  app.set('view engine', 'jade');
  app.use(express.bodyParser());
  app.use(express.methodOverride());
  app.use(app.router);
  app.use(express.static(__dirname + '/public'));
});

(等等。)

app.get('/memo', function(req, res) {
  console.log("index");
  Memo.find({}, function(err, data) {
    if(err) return next(err);
    res.render('index', { memos: data });
  });
});

这是另一个:

app.get('/memo/list', function(req, res, next) {
  console.log("get memos");
  Memo.find({}, function(err, data) {
    if(err) return next(err);
    res.json(data);
  });
});

取自于构建在节点上简单记事本

这些是困扰我的问题:

  1. 到底是next/next();做什么的?如果不存在会发生什么?
  2. 为什么第二部分next作为参数而第一部分不是参数?

编辑:


阅读 337

收藏
2020-07-07

共1个答案

一尘不染

Express使用具有回调的中间件函数(动作完成时调用的函数),而next具有此目的(这是触发Express堆栈中下一个中间件的回调)。所有Express中间件(与Connect兼容)具有3个参数:请求,响应,下一个(可选)。

例如,静态中间件提供静态文件,csrf中间件在接收POST请求时检查参数,并处理路由的路由器中间件(上面粘贴的内容是其中的一部分)。

每个中间件都可以完成其任务,并next在满足某些条件的情况下调用队列中的中间件(例如,静态中间件不会调用下一个中间件,因为它会自行处理文件,以便路由器可以。)不会被打电话)。

在路由器中,您通常不调用next它,因为它往往是最后执行的中间件(除非您需要基准测试之类的东西)。

如果您要创建一个拒绝访问所有未登录用户的中间件,则next()仅在该用户登录后才必须调用(这样才能调用下一个中间件,在这种情况下,路由器可以使用户访问他们正在寻找的页面),否则您可能会将他们重定向到登录页面。

next 完全不接受任何参数或将错误作为参数。

编辑:根据您的配置,路由器在静态中间件之前,因此,如果要提供文件,则需要声明一个通配符路由,当路由不匹配时调用next():

app.get('*', function (req, res, next) {
  // no route is matched
  // so call next() to pass to the static middleware
  next();
});

注意:我不建议您将静态文件服务器放在路由器之后,建议您将其放在路由器之前,以便可以定义自己的自定义404路由。

2020-07-07