expression下一个function,它真的是什么?

一直试图findnext()方法的一个很好的描述。 在Express文档中,它表示可以使用next('route')跳转到该路由并跳过其间的所有路由,但是有时next被调用,而没有参数。 任何人都知道一个很好的教程等,描述nextfunction?

next()没有参数说“只是在开玩笑,我实际上不想要处理这个”。 它回来,并试图find下一个匹配的路线。

这很有用,比如说如果你想拥有一些带有url slug的页面pipe理器,还有很多其他的东西,但是这里有一个例子。

 app.get('/:pageslug', function(req, res, next){ var page = db.findPage(req.params.pageslug); if (page) { res.send(page.body); } else { next(); } }); app.get('/other_routes', function() { //... }); 

构成代码应该检查一个数据库的页面与一个特定的ID段塞。 如果它发现一个渲染它! 如果它没有find一个然后忽略这个路由处理程序,并检查其他的。

所以next()没有参数允许假装你没有处理路由,所以别的东西可以拿起来。


或与app.all('*')计数器。 这可以让你执行一些共享的设置代码,然后转到其他路线做更具体的事情。

 app.all('*', function(req, res, next){ myHitCounter.count += 1; next(); }); app.get('/other_routes', function() { //... }); 

在大多数框架中,你会得到一个请求,并且你想返回一个响应。 由于Node.js的asynchronous特性,如果你正在做非重要的事情,你会遇到嵌套的callback问题。 为了避免这种情况发生,Connect.js(在v4.0之前,Express.js是connect.js之上的一个层)有一些被称为中间件的东西,它是一个具有2,3或4个参数的函数。

 function (<err>, req, res, next) {} 

您的Express.js应用程序是这些function的堆栈。

在这里输入图像说明

路由器是特殊的,它是中间件,可以让你执行一个或多个中间件的特定url。 所以它是一个堆栈内的堆栈。

那么下一步呢? 简单来说,它会告诉您的应用程序运行下一个中间件。 但是当你传递给下一个时会发生什么? Express将中止当前的堆栈并运行所有具有4个参数的中间件。

 function (err, req, res, next) {} 

这个中间件用来处理任何错误。 我喜欢做以下事情:

 next({ type: 'database', error: 'datacenter blew up' }); 

有了这个错误,我可能会告诉用户出了问题,并logging下真正的错误。

 function (err, req, res, next) { if (err.type === 'database') { res.send('Something went wrong user'); console.log(err.error); } }; 

如果您将Express.js应用程序作为一个堆栈来绘制,那么您可能会自己修复很多奇怪的问题。 例如,当您在路由器后添加Cookie中间件时,您的路由不会有Cookie。

恕我直言,这个问题接受的答案是不是真的准确。 其他人的回答是正确的,但我想提供更多的代码,使其更具体。 说你有这个简单的快递应用程序:

 var express = require('express'); var app = express(); app.get('/user/:id', function (req, res, next) { console.log('before request handler'); next(); }); app.get('/user/:id', function (req, res, next) { console.log('handling request'); res.sendStatus(200); next(); }); app.get('/user/:id', function (req, res, next) { console.log('after request handler'); next(); }); app.listen(3000, function () { console.log('Example app listening on port 3000!') }); 

如果你这样做

 curl http://localhost:3000/user/123 

你会看到这个打印到控制台:

 before request handler handling request after request handler 

现在,如果你在中间处理程序中注释掉对next()的调用,如下所示:

 app.get('/user/:id', function (req, res, next) { console.log('handling request'); res.sendStatus(200); //next(); }); 

你会在控制台上看到这个:

 before request handler handling request 

请注意,最后一个处理程序( after request handler打印的after request handler )不能运行。 那是因为你不再用快递来运行下一个处理程序。

所以,如果你的“主”处理程序(返回200)成功或者不成功,如果你想让其他的中间件运行,你必须调用next()

例如,假设您要logging所有进入某个数据库的请求,而不pipe请求是否成功。 如果在主要请求处理程序之后的中间件中处理该请求,则必须在主要处理程序中调用next() ,否则logging器将不会运行。

next()不带参数调用框架中的下一个路由处理程序。