假设您有这样一个简单的代码块:

app.get('/', function(req, res){
    res.send('Hello World');
});

该函数有两个参数reqres,分别代表请求和响应对象.

另一方面,还有第三个参数为next的其他函数.例如,让我们看一下以下代码:

app.get('/users/:id?', function(req, res, next){ // Why do we need next?
    var id = req.params.id;
    if (id) {
        // do something
    } else {
        next(); // What is this doing?
    }
});

我不明白next()的意义是什么,为什么要用它.在那个例子中,如果id不存在,next实际上在做什么?

推荐答案

它将控制权转移到下一条matching路由.例如,在您给出的示例中,如果给定了id,您可能会在数据库中查找用户,并将其分配给req.user.

在下面,你可以 Select 这样的路由:

app.get('/users', function(req, res) {
  // check for and maybe do something with req.user
});

由于/users/123将首先匹配示例中的路由,因此将首先判断并查找用户123;然后/users可以用这个结果做点什么.

不过,在我看来,Route middleware是一个更灵活、更强大的工具,因为它不依赖于特定的URI方案或路由排序.我倾向于对如下示例进行建模,假设Users模型带有异步findOne():

function loadUser(req, res, next) {
  if (req.params.userId) {
    Users.findOne({ id: req.params.userId }, function(err, user) {
      if (err) {
        next(new Error("Couldn't find user: " + err));
        return;
      }

      req.user = user;
      next();
    });
  } else {
    next();
  }
}

// ...

app.get('/user/:userId', loadUser, function(req, res) {
  // do something with req.user
});

app.get('/users/:userId?', loadUser, function(req, res) {
  // if req.user was set, it's because userId was specified (and we found the user).
});

// Pretend there's a "loadItem()" which operates similarly, but with itemId.
app.get('/item/:itemId/addTo/:userId', loadItem, loadUser, function(req, res) {
  req.user.items.append(req.item.name);
});

能够像这样控制流量非常方便.您可能希望某些页面仅对具有管理员标志的用户可用:

/**
 * Only allows the page to be accessed if the user is an admin.
 * Requires use of `loadUser` middleware.
 */
function requireAdmin(req, res, next) {
  if (!req.user || !req.user.admin) {
    next(new Error("Permission denied."));
    return;
  }

  next();
}

app.get('/top/secret', loadUser, requireAdmin, function(req, res) {
  res.send('blahblahblah');
});

希望这能给你一些启发!

Node.js相关问答推荐

如何处理EPIPE时,使用axios并期待413响应?

当变量在另一个文件中初始化时,在初始化错误之前无法访问变量

Mongoose:如何使用填充进行查找

如何修复我的 NodeJS SSE 写入函数以在后续调用中更新 HTML?

express 和 mongoose 的新密码不正确

级联定时器和Jest 的异步功能

在 nodejs 中使用 multer 上传文件返回未定义的 req.file 和空的 req.body

MongoDB 根据使用聚合的条件从嵌套数组中删除对象

如何使用来自前一阶段的另一个数组的聚合mongoose 在数组中添加字段

NestJS 共享模块的问题

在安装 tensorflow 时遇到问题

node_modules 中 .bin 文件夹的用途是什么?

如何正确使用 package.json 中的关键字属性?

如何以编程方式检测nodejs中的调试模式?

将 myproject/.npmrc 与注册表一起使用

如何在 NodeJs 中下载和解压缩内存中的 zip 文件?

有人在 NodeJS 中实现过 wiki 吗?

fs.createWriteStream 不会立即创建文件?

如何仅在丢失的路由上将 Express.js 设置为 404?

FireStore 如果不存在则创建一个文档