假设您有一个简单的代码块,如下所示:
app.get('/', function(req, res){
res.send('Hello World');
});
此函数有两个参数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?
}
});
我不明白next()
的意义是什么,也不明白为什么要使用它。在那个例子中,如果id不存在,那么next
实际上在做什么?
6条答案
按热度按时间hujrc8aj1#
它将控制权传递给下一个匹配的路由。例如,在你给予的例子中,如果给定了
id
,你可以在数据库中查找用户,并将其分配给req.user
。在下面,您可以使用如下路线:
由于/users/123将首先匹配示例中的路由,因此它将首先检查并找到用户
123
;那么/users
可以对这个结果做些什么。但是,在我看来,Route middleware是一个更灵活、更强大的工具,因为它不依赖于特定的URI方案或路由顺序。
能够像这样控制流程是非常方便的。您可能希望某些页面只对带有管理员标志的用户可用:
希望这给了你一些启发!
68bkxrlz2#
我在理解next()时也遇到了问题,但this帮助了我
pprl5pva3#
在理解 *
next
* 之前,你需要对节点中的请求-响应循环有一点了解,尽管没有太多细节。它从你对一个特定资源发出HTTP请求开始,当你向用户发送一个响应时结束,也就是当你遇到res.send('Hello World');让我们看一个非常简单示例。
这里我们不需要next(),因为resp.send将结束循环并将控制权交回给路由中间件。
现在让我们看另一个例子。
在这里,我们有两个中间件函数用于相同的路径。但是你总是会从第一个函数得到响应。因为它是第一个安装在中间件堆栈中的,res.send将结束循环。
但是,如果我们总是不希望返回“Hello World!!!!”响应,在某些情况下,我们可能希望返回“Hello Planet!!!!”响应,让我们修改上面的代码,看看会发生什么。
next
在这里做什么呢?是的,你可能会有猜测,如果条件为真,它会跳过第一个中间件函数,调用下一个中间件函数,你会得到"Hello Planet !!!!"
的响应。因此,接下来将控制传递给中间件堆栈中的下一个函数。
如果第一个中间件功能没有发送回任何响应,但执行了一段逻辑,然后您从第二个中间件功能得到了响应,会怎么样?
类似以下内容:-
在这种情况下,您需要调用两个中间件函数。因此,到达第二个中间件函数的唯一方法是调用next();
如果你不调用next呢?不要指望第二个中间件函数会自动被调用。在调用第一个函数后,你的请求将被挂起。第二个函数将永远不会被调用,你也不会得到响应。
ulydmbyx4#
Next用于将控制传递给下一个中间件功能。如果不是,则请求将保持挂起或打开状态。
sz81bmfz5#
我还想补充一下为什么
express
不调用下一个中间件,而是让我们控制它。由于节点是异步的,如果express调用下一个中间件而不等待某个异步调用完成,那么响应可能不完整或包含错误,因此用户可以控制何时应该调用下一个中间件函数。g6ll5ycj6#
express
app
handle
函数的主要作用是向客户端发送一个响应,并终止request-response cycle
。而终止这个循环可以由response methods
中的一个来完成(例如,资源end()、资源json这意味着如果中间件或route handler
执行了一些操作,但随后没有调用response methods
中的一个,也没有将控制传递给下一个处理程序或中间件,request-response cycle
将不会被终止。但是next
的作用取决于它被调用的位置和方式。为了管理不同的任务(路由处理器、中间件),
express
创建了stacks
。它们看起来像是tasks
的queue
。每个router
和route
创建了它自己的tasks
的stack
;函数的
use
方法将task
(middleware
函数)添加到router
的stack
中。app.get
、app.post
等创建单独的route
(具有其自己的stack
,并将route
的实际handlers
推送到它)在router
中,然后将这些route
处理程序推送到函数中 Package 的router
。也就是说,当在router
stack
中创建了一个route
时,类似于route
task
( Package 函数),并推送了subtasks
。因为
router
有它自己的stack
,所以不带参数调用next
只能得到route
的下一个处理程序:在
middleware
内调用next
(express
建议应用use
方法来挂载middleware
)会使我们进入router
的下一个route
或middleware
,因为middleware
(挂载时)被推送到router
stack
。next
接受不同的参数。任何不是'route'
或'router'
的参数都将被视为错误,并将被传递给error
middleware
,该error
必须在所有路由之后装载,并具有四个参数:将字符串
'route'
作为next
的参数,将跳过所有剩余的route
handlers
,并获取router
的下一个route
:将字符串
'router'
作为next
的参数,使我们脱离当前的router
: