Nodejs express4.x的app.use与router.use的优先级
Nodejs express4.x的app.use与router.use的优先级
express4.x,将express的自带中间件都独立出来了。独立出来的一个模块还有router。 想请问下。这之后,app.use与router.use这两个方法注册的中间件执行时有优先级吗。
Nodejs express4.x的app.use与router.use的优先级
在Express 4.x版本中,app.use
和 router.use
方法用于注册中间件。虽然它们的功能相似,但在实际应用中可能会遇到一些细微的差别。本文将探讨这两个方法在中间件执行顺序上的差异。
app.use vs router.use
-
app.use:
app.use
是全局中间件,应用于整个应用程序。它可以处理所有路由请求。- 它通常用于设置全局中间件,如错误处理、日志记录等。
-
router.use:
router.use
是局部中间件,仅应用于特定的路由或一组路由。- 它可以用于对特定路由进行预处理或后处理。
执行顺序
在Express应用中,中间件的执行顺序非常重要。app.use
和 router.use
注册的中间件会根据它们被添加到应用中的顺序来执行。具体来说:
- 如果你在一个路由之前使用
app.use
添加了一个中间件,那么这个中间件会在所有匹配该路由的请求之前执行。 - 同样地,如果在某个路由处理器之前使用
router.use
添加了一个中间件,那么这个中间件会在所有匹配该路由的请求之前执行。
示例代码
const express = require('express');
const app = express();
const router = express.Router();
// 全局中间件
app.use((req, res, next) => {
console.log('Global middleware: Before route');
next();
});
// 路由中间件
router.use((req, res, next) => {
console.log('Route middleware: Before route handler');
next();
});
// 路由处理器
router.get('/', (req, res) => {
res.send('Hello World!');
});
// 将路由挂载到应用
app.use('/api', router);
// 错误处理中间件
app.use((err, req, res, next) => {
console.error(err.stack);
res.status(500).send('Something broke!');
});
app.listen(3000, () => {
console.log('Server is running on port 3000');
});
在这个例子中:
- 当访问
/api/
时,首先会触发全局中间件app.use
。 - 然后会触发路由中间件
router.use
。 - 最后,路由处理器
router.get
会被调用。 - 如果在处理过程中发生错误,错误处理中间件
app.use
会被触发。
总结来说,app.use
和 router.use
的执行顺序取决于它们被添加到应用中的位置。全局中间件通常先于局部中间件执行,但具体的顺序取决于它们在代码中的排列顺序。
补充下说明。执行时的优先级指的是。.use方法在express3.x及之前是先注册,先响应。 然后现在有两个对象下的.use方法(app.use和router.use),他们注册的中间件执行时天生就有优先级别吗。(举个 极端的例子就是是先响应完app.use再响应router.use。还是仍然一视同仁,先注册,先响应?)
看源码就知道了,app.use调用的是Router的实例_router.use,即Router的原型方法,跟router.use一样
this._router = new Router({
caseSensitive: this.enabled('case sensitive routing'),
strict: this.enabled('strict routing')
});
var proto = module.exports = function(options) {
options = options || {};
function router(req, res, next) {
router.handle(req, res, next);
}
// mixin Router class functions
router.proto = proto;
router.params = {};
router._params = [];
router.caseSensitive = options.caseSensitive;
router.strict = options.strict;
router.stack = [];
return router;
};
但是看调用每次调用组件’var router = express.Router([options]);‘都是返回一个新的function,有自己的stack。
最后,看了一下文档…
router.use
需要调用app.use(’/foo’, router);
才会生效啊!所以没有优先级的关系。
最后一句正解啊!没有认真重新看文档。当时想着问题的时候也懒得去找源码看,惭愧= =。佩服你思考的方式。从源码出发,然后发现
但是看调用每次调用组件'var router = express.Router([options]);'都是返回一个新的function,有自己的stack。
这个问题,再翻阅文档,最后得到答案。 要向你学习这种思考的方式,感谢。
在Express 4.x中,app.use
和 router.use
注册的中间件没有严格的优先级关系。它们的执行顺序取决于它们被注册的先后顺序。
具体来说:
app.use
是应用级别的中间件,它作用于整个应用程序,适用于所有路由。router.use
是路由级别的中间件,它仅作用于特定的路由路径。
当你在一个应用中同时使用 app.use
和 router.use
时,它们的执行顺序依赖于它们被注册的顺序。通常情况下,先注册的中间件会先执行。
示例代码
const express = require('express');
const app = express();
const router = express.Router();
// 应用级别的中间件
app.use((req, res, next) => {
console.log('App-level middleware executed');
next();
});
// 路由级别的中间件
router.use((req, res, next) => {
console.log('Router-level middleware executed');
next();
});
// 定义一个路由,使用这个路由中间件
router.get('/', (req, res) => {
res.send('Hello World!');
});
// 将路由挂载到应用
app.use('/path', router);
app.listen(3000, () => {
console.log('Server is running on port 3000');
});
执行顺序
假设你访问 /path/
,输出将会是:
App-level middleware executed
Router-level middleware executed
这是因为 app.use
先于 router.use
被注册。如果 router.use
先于 app.use
注册,那么输出顺序将会相反。
总结
app.use
和router.use
没有内在的优先级。- 它们的执行顺序取决于它们被注册的先后顺序。
app.use
对应应用级别,而router.use
对应路由级别。
通过理解这些基本概念,你可以更好地管理和组织你的中间件逻辑。