假设您有一个简单的代码块,如下所示:
app.get('/', function(req, res){
res.send('Hello World');
});
Run Code Online (Sandbox Code Playgroud)
这个函数有两个参数,req并且res,它们分别代表所述请求和响应对象.
另一方面,还有其他函数,第三个参数被调用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?
}
});
Run Code Online (Sandbox Code Playgroud)
我无法理解next()它的用途是什么或为什么被使用.在那个例子中,如果id不存在,那next实际上在做什么?
Ash*_*she 246
它将控制传递给下一个匹配的路径.例如,在给出的示例中,如果给出了用户,则可以在数据库中查找该用户id,并将其分配给req.user.
下面,你可以有一条路线:
app.get('/users', function(req, res) {
// check for and maybe do something with req.user
});
Run Code Online (Sandbox Code Playgroud)
由于/ users/123将首先匹配您示例中的路由,因此将首先检查并查找用户123; 然后/users可以做一些事情的结果.
路由中间件(注意:链接到2.x文档,但这是在3.x上进行测试)是一个更灵活和强大的工具,但在我看来,因为它不依赖于特定的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);
});
Run Code Online (Sandbox Code Playgroud)
能够像这样控制流量非常方便.您可能希望某些页面仅对具有admin标志的用户可用:
/**
* 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');
});
Run Code Online (Sandbox Code Playgroud)
希望这能给你一些灵感!
raj*_*esk 73
我也有问题理解的next(),但这种帮助
var app = require("express")();
app.get("/", function(httpRequest, httpResponse, next){
httpResponse.write("Hello");
next(); //remove this and see what happens
});
app.get("/", function(httpRequest, httpResponse, next){
httpResponse.write(" World !!!");
httpResponse.end();
});
app.listen(8080);
Run Code Online (Sandbox Code Playgroud)
Mav*_*v55 45
在理解之前next,您需要对节点中的请求 - 响应周期有一点了解,但不是很详细.它从您为特定资源发出HTTP请求开始,当您将响应发送回用户时,即当您遇到res.send('Hello World')之类的内容时,它会结束;
让我们来看一个非常简单的例子.
app.get('/hello', function (req, res, next) {
res.send('USER')
})
Run Code Online (Sandbox Code Playgroud)
这里我们不需要next(),因为resp.send将结束循环并将控制权移交给路由中间件.
现在让我们来看看另一个例子.
app.get('/hello', function (req, res, next) {
res.send("Hello World !!!!");
});
app.get('/hello', function (req, res, next) {
res.send("Hello Planet !!!!");
});
Run Code Online (Sandbox Code Playgroud)
这里我们有2个中间件函数用于相同的路径.但你总会从第一个得到回应.因为它首先安装在中间件堆栈中,res.send将结束循环.
但是如果我们总是不想要"Hello World !!!!"回复怎么办呢.在某些情况下,我们可能想要"Hello Planet !!!!" 响应.让我们修改上面的代码,看看会发生什么.
app.get('/hello', function (req, res, next) {
if(some condition){
next();
return;
}
res.send("Hello World !!!!");
});
app.get('/hello', function (req, res, next) {
res.send("Hello Planet !!!!");
});
Run Code Online (Sandbox Code Playgroud)
这是next做什么的.是的,你可能有gusses.如果条件为真,它将跳过第一个中间件函数并调用下一个中间件函数,您将获得"Hello Planet !!!!"响应.
因此,接下来将控件传递给中间件堆栈中的下一个函数.
如果第一个中间件函数没有发回任何响应但是执行一个逻辑然后从第二个中间件函数得到响应,该怎么办?
如下所示: -
app.get('/hello', function (req, res, next) {
// Your piece of logic
next();
});
app.get('/hello', function (req, res, next) {
res.send("Hello !!!!");
});
Run Code Online (Sandbox Code Playgroud)
在这种情况下,您需要调用两个中间件函数.因此,到达第二个中间件函数的唯一方法是调用next();
如果你不拨打下一个电话怎么办?不要指望第二个中间件函数会自动调用.在调用第一个函数后,您的请求将被挂起.第二个函数永远不会被调用,你不会得到回复.
小智 8
Next用于将控制传递给下一个中间件函数.如果不是,请求将被挂起或打开.