一直在试图找到一种很好的next()
方法描述。在Express文档中,它说next('route')
可用于跳转到该路由并跳过其间的所有路由,但有时next
被称为没有参数。有人知道描述该next
功能的优秀教程等吗?
一直在试图找到一种很好的next()
方法描述。在Express文档中,它说next('route')
可用于跳转到该路由并跳过其间的所有路由,但有时next
被称为没有参数。有人知道描述该next
功能的优秀教程等吗?
Answers:
next()
毫无争议的说法是“开玩笑,我实际上并不想处理这个问题”。它返回并尝试查找将匹配的下一条路线。
这很有用,例如,如果您想使用某种带有URL插件的页面管理器以及许多其他功能,但这是一个示例。
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标记的页面。如果找到一个渲染器!如果找不到,则忽略此路由处理程序并检查其他路由处理程序。
因此next()
,没有参数就可以假装您没有处理该路线,以便其他人可以选择它。
或点击app.all('*')
。这使您可以执行一些共享的设置代码,然后转到其他路线以执行更具体的操作。
app.all('*', function(req, res, next){
myHitCounter.count += 1;
next();
});
app.get('/other_routes', function() {
//...
});
next('route')
特定于@,app.VERB()
并且在路由具有多个回调以“ 绕过其余路由回调 ”时next(err)
使用。@用于跳转到任何“ 错误中间件 ”(E
从帖子中)。
next()
不带参数的调用并不能真正告诉系统“我不想处理”,它只是告诉系统完成此操作后继续处理任何剩余的中间件。调用不是错误条件next()
,它是正常流程的一部分。如果您不拨打电话,next()
将不会处理其他任何路由。
在大多数框架中,您都会收到一个请求,并且想要返回一个响应。由于Node.js的异步特性,如果您做的是琐碎的事情,则会遇到嵌套回调的问题。为了避免这种情况的发生,Connect.js(v4.0之前的Express.js是connect.js之上的一层)具有称为中间件的功能,该中间件具有2、3或4个参数。
function (<err>, req, res, next) {}
您的Express.js应用程序是这些功能的堆栈。
路由器很特殊,它是一种中间件,可让您针对某个URL执行一个或多个中间件。所以它是一个堆栈中的一个堆栈。
那么接下来该怎么办?很简单,它告诉您的应用程序运行下一个中间件。但是,当您将某些内容传递给下一个内容时会发生什么?Express将中止当前堆栈,并运行具有4个参数的所有中间件。
function (err, req, res, next) {}
该中间件用于处理任何错误。我喜欢执行以下操作:
next({ type: 'database', error: 'datacenter blew up' });
遇到这个错误,我可能会告诉用户出了什么问题并记录了真正的错误。
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
)没有运行。那是因为您不再告诉Express运行下一个处理程序。
因此,您的“主”处理程序(返回200的处理程序)是否成功并不重要,如果您想运行其余的中间件,则必须调用next()
。
什么时候派上用场?假设您要记录进入某个数据库的所有请求,而不管请求是否成功。
app.get('/user/:id', function (req, res, next) {
try {
// ...
}
catch (ex) {
// ...
}
finally {
// go to the next handler regardless of what happened in this one
next();
}
});
app.get('/user/:id', function (req, res, next) {
logToDatabase(req);
next();
});
如果要运行第二个处理程序,则必须调用next()
第一个处理程序。
请记住,该节点是异步的,因此它不知道第一个处理程序的回调何时完成。您必须通过致电告知next()
。
还询问了有关next('route')的使用的问题,到目前为止,似乎已在提供的答案中涵盖了next('route'):
简而言之:下一个中间件功能。
从此Express JS官方文档中摘录-“写作中间件”页面:
“中间件函数myLogger只是打印一条消息,然后通过调用next()函数将请求传递给堆栈中的下一个中间件函数。”
var express = require('express')
var app = express()
var myLogger = function (req, res, next) {
console.log('LOGGED')
next()
}
app.use(myLogger)
app.get('/', function (req, res) {
res.send('Hello World!')
})
app.listen(3000)
Express JS文档的此页面指出:“如果当前中间件函数未结束请求-响应周期,则必须调用next()将控制权传递给下一个中间件函数。否则,请求将被挂起。”
简而言之:下一路线(与下一中间件功能))
“要从路由器中间件堆栈中跳过其余中间件功能,请调用next('route')将控制权传递给下一条路由。注意:next('route')仅在使用app.METHOD()或router.METHOD()函数。
此示例显示了一个中间件子堆栈,该子堆栈处理对/ user /:id路径的GET请求。”
app.get('/user/:id', function (req, res, next) {
// if the user ID is 0, skip to the next route
if (req.params.id === '0') next('route')
// otherwise pass the control to the next middleware function in this stack
else next()
}, function (req, res, next) {
// render a regular page
res.render('regular')
})
// handler for the /user/:id path, which renders a special page
app.get('/user/:id', function (req, res, next) {
res.render('special')
})
next()是带有req的中间件函数的回调参数,res是以下代码中next的http请求和响应参数。
app.get('/',(req,res,next)=> {next()});
因此,next()调用传入的中间件函数。如果当前的中间件函数未结束请求-响应周期,则应调用next(),否则请求将被挂起并超时。
当将多个中间件函数传递给app.use或app.METHOD时,需要在每个中间件函数中调用next() fn ,否则将不调用下一个中间件函数(如果传递了多个中间件函数)。要跳过对其余中间件函数的调用,请在中间件函数内调用next('route'),此后不应再调用其他中间件函数。在下面的代码中,将调用fn1并且还将调用fn2,因为在fn1中调用了next()。但是,不会调用fn3,因为在fn2中调用了next('route')。
app.get('/fetch', function fn1(req, res, next) {
console.log("First middleware function called");
next();
},
function fn2(req, res, next) {
console.log("Second middleware function called");
next("route");
},
function fn3(req, res, next) {
console.log("Third middleware function will not be called");
next();
})