update middlewareX

This commit is contained in:
wjqserver 2025-06-18 08:47:20 +08:00
parent 00b9c283d1
commit f434f517d4

View file

@ -1,89 +1,72 @@
package touka
// UseChainIf 是一个条件中间件包装器。
// 如果 `condition` 为 true它将执行提供的 `middlewares` 链。
// 如果 `condition` 为 false它会直接跳过这些中间件调用下一个处理器。
func (engine *Engine) UseChainIf(condition bool, middlewares ...HandlerFunc) HandlerFunc {
if !condition {
type MiddlewareXFunc func() HandlerFunc
// UseChainIf 是一个条件中间件包装器,用于一组中间件
// 如果 `condition` 为 true它将按顺序创建并执行提供的 `factories` 生成的中间件链
// 否则,它会直接跳过整个链
func (engine *Engine) UseChainIf(condition bool, factories ...MiddlewareXFunc) HandlerFunc {
// 如果条件不满足或没有提供任何工厂函数,返回一个“穿透”中间件
if !condition || len(factories) == 0 {
return func(c *Context) {
c.Next()
}
}
// 如果条件为真,返回一个处理器,该处理器负责执行子链。
// 我们通过修改 Context 的状态来做到这一点。
// 这比递归闭包或替换 c.Next 要清晰。
// 在配置路由时就创建好所有中间件实例
middlewares := make(HandlersChain, 0, len(factories))
for _, factory := range factories {
if factory != nil {
middlewares = append(middlewares, factory())
}
}
// 返回一个处理器,该处理器负责执行这个子链
// 这个实现通过临时替换 Context 的处理器链来注入子链,是健壮的
return func(c *Context) {
// 1. 将当前的处理链和索引位置保存下来。
// 将当前的处理链和索引位置保存下来
originalHandlers := c.handlers
originalIndex := c.index
// 2. 创建一个新的处理链,它由传入的中间件和最后的 "恢复并继续" 处理器组成。
// 创建一个新的临时处理链
// 它由我们预先创建的 `middlewares` 和一个特殊的“恢复”处理器组成
subChain := make(HandlersChain, len(middlewares)+1)
copy(subChain, middlewares)
// 3. 在子链的末尾添加一个特殊的 handler。
// 它的作用是恢复原始的处理链状态,并继续执行原始链中 `If` 之后的处理器。
// 在子链的末尾添加“恢复”处理器
// 当所有 `middlewares` 都执行完毕并调用了 Next() 后,这个函数会被执行
subChain[len(middlewares)] = func(ctx *Context) {
// 恢复原始的处理链状态
ctx.handlers = originalHandlers
ctx.index = originalIndex
// 继续执行原始处理链中 `UseChainIf` 之后的下一个处理器
ctx.Next()
}
// 4. 将 Context 的处理器链临时替换为我们的子链,并重置索引。
// 将 Context 的处理器链临时替换新的的子链,并重置索引以从头开始
c.handlers = subChain
c.index = -1
// 5. 调用 c.Next() 来启动子链的执行。
c.Next()
}
}
// UseIf 是一个条件中间件包装器
func (engine *Engine) UseIf(condition bool, middlewares HandlerFunc) HandlerFunc {
func (engine *Engine) UseIf(condition bool, middlewareX MiddlewareXFunc) HandlerFunc {
if !condition {
return func(c *Context) {
c.Next()
}
}
return middlewares
}
// 只有当条件为 true 时,才调用工厂函数创建中间件实例
// 注意:这会导致每次请求都创建一个新的中间件实例(如果中间件本身有状态)
// 如果中间件是无状态的,可以进行优化
func (engine *Engine) UseNewChainIf(condition bool, middlewares ...HandlerFunc) HandlerFunc {
// 如果条件不满足或没有提供中间件,返回一个“穿透”中间件。
if !condition || len(middlewares) == 0 {
return func(c *Context) {
c.Next()
}
}
// 优化:只创建一次
middleware := middlewareX()
// 如果条件满足,返回一个处理器,该处理器负责按顺序执行这个子链。
return func(c *Context) {
// 保存原始的处理链和当前执行索引,以便在子链结束后恢复。
originalHandlers := c.handlers
originalIndex := c.index
// 创建一个新的临时处理链。
// 这个链由传入的 `middlewares` 和一个特殊的“恢复”处理器组成。
subChain := make(HandlersChain, len(middlewares)+1)
copy(subChain, middlewares)
// 在子链的末尾添加“恢复”处理器。
// 当所有 `middlewares` 都执行完毕并调用了 Next() 后,这个函数会被执行。
subChain[len(middlewares)] = func(ctx *Context) {
// 恢复原始的处理链状态。
ctx.handlers = originalHandlers
ctx.index = originalIndex
// 继续执行原始处理链中 `ChainIf` 之后的下一个处理器。
ctx.Next()
}
// 将 Context 的处理器链临时替换为我们的子链,并重置索引以从头开始。
c.handlers = subChain
c.index = -1
// 调用 c.Next() 来启动这个子链的执行。
c.Next()
middleware(c)
}
}