Golang middleware 链式调用

wallywl / 2023-05-10 / 原文

 

    基于web的Golang middleware 链式调用,原文地址在如下  gowebexamples

https://gowebexamples.com/advanced-middleware/

对其调用过程简化如下;

package main

import (
    "fmt"
    "time"
)

type HandlerFunc func()

type Middleware func(HandlerFunc) HandlerFunc

func Timing(x int) Middleware {

    return func(f HandlerFunc) HandlerFunc {
        return func() {
            start := time.Now()

            defer func() {
                fmt.Println("elapse ", time.Since(start))
            }()

            fmt.Println("in timing", x)

            f()
        }
    }
}

func Method(s string) Middleware {

    return func(f HandlerFunc) HandlerFunc {
        return func() {
            fmt.Println("in method ", s)

            f()
        }
    }
}

func Chain(f HandlerFunc, middlerwares ...Middleware) HandlerFunc {
    for _, m := range middlerwares {
        f = m(f)
    }

    return f
}

func Hello() {
    fmt.Println("in Hello")
}

func iterate(f HandlerFunc) {
    f()
}

func main() {

    iterate(Chain(Hello, Timing(5), Method("get")))
}

 

        调用过程为,在Chain 函数中,Hello 函数作为第一个参数, 调用Timing(5) 后的返回值,匿名函数

func(f HandlerFunc) HandlerFunc,作为第二参数, 调用Method("get")后的返回值,匿名函数作为第三个参数。
  遍历每个middleware ,调用第一个Timing(5)的返回值,匿名函数时,将Hello 函数作为参数,此时,匿名函数的返回值中的
f() 即为Hello 函数。返回值为一个包含了Timing 和Hello 函数的
return func() 函数,
将此时的返回值作为参数赋值给调用的Method 函数,
遍历结束后,返回此时的函数,即Method 中的包含打印信息和 f() 的函数。
在iterate 中调用上面的最后一个返回函数,就会依次打印:

in method get
in timing 5
in Hello
elapse 0s