Express可配置中间件中req、res、next参数来源疑问
Express可配置中间件req/res/next参数传递原理
核心逻辑本质是两层函数分工+Express框架内部自动传参,你在业务代码里看不到参数传递是因为注入逻辑被框架封装了,具体执行流程拆解如下:
- 第一层是中间件工厂函数:你写的
module.exports = function(options) {}就是工厂,调用mw({option1: '1', option2: '2'})时会立刻执行这层函数,它的作用是接收自定义配置,通过JS闭包把配置缓存住,最后返回一个符合Express规范的标准中间件函数。 - 你传给
app.use()的从来不是外层的工厂函数,而是工厂执行后返回的、签名为function(req, res, next) {}的内层函数,app.use()收到这个函数后只会把它存入内部的中间件执行栈,不会立刻调用。 - 当真实HTTP请求到达服务时,Express会按照中间件栈的注册顺序遍历执行,遍历过程中框架会自动给每个中间件函数传入三个参数:当前请求的
req对象、响应操作的res对象、控制中间件链流转的next函数,整个传参过程是Express内部实现的,不需要业务代码手动处理。
和普通无配置中间件的对比
你觉得参数逻辑"看不到",只是因为可配置中间件多了一层工厂包装,和普通中间件的核心逻辑完全一致:
// 普通无配置中间件:直接把标准中间件函数传给app.use function commonMw(req, res, next) { // 业务逻辑 next() } app.use(commonMw)
上面这个普通写法里,你同样没有在业务代码里手动给commonMw传req/res/next,这三个参数同样是Express在请求到来时内部传入的。可配置中间件只是多了一步"传配置拿中间件实例"的步骤,后续的执行逻辑完全没有区别。
Express内部传参的极简伪代码参考
你可以通过下面的简化实现理解框架内部的传参动作:
// 内部维护的中间件栈 const middlewareStack = [] // app.use的简化实现:仅做中间件注册存储 function use(middleware) { middlewareStack.push(middleware) } // 请求到达时的处理逻辑 function onRequest(req, res) { let stackIndex = 0 // 内置的next流转函数 function next() { const currentMw = middlewareStack[stackIndex++] // 所有中间件执行完就结束 if (!currentMw) return // 这里就是Express自动给中间件传三个参数的位置 currentMw(req, res, next) } // 启动中间件执行链 next() }
内层中间件能访问外层传入的
options,是JS闭包的特性:内层函数在定义时就捕获了外层作用域的options变量,等后续请求到来执行内层函数时,依然可以访问到当初调用工厂函数时传入的配置值。
内容的提问来源于stack exchange,提问作者Aravind HT
相关产品推荐
相关产品推荐

