中间件执行流程

时间:2019-03-25 08:24:22

标签: go

我无法掌握这段代码的执行流程:

func middlewareOne(next http.Handler) http.Handler {
    return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
        log.Println("Executing middlewareOne")
        next.ServeHTTP(w, r)
        log.Println("Executing middlewareOne again")
        next.ServeHTTP(w, r)
        log.Println("Executing middlewareOne yupiii")
    })
}

func middlewareTwo(next http.Handler) http.Handler {
    return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
        log.Println("Executing middlewareTwo")
        next.ServeHTTP(w, r)
        log.Println("Executing middlewareTwo again")
        next.ServeHTTP(w, r)
    })
}

func final(w http.ResponseWriter, r *http.Request) {
    log.Println("Executing finalHandler")
    w.Write([]byte("OK"))
}

func main() {
    finalHandler := http.HandlerFunc(final)
    http.Handle("/", middlewareOne(middlewareTwo(finalHandler)))
    http.ListenAndServe(":3000", nil)
}

输出:

2019/03/25 09:16:32 Executing middlewareOne
2019/03/25 09:16:32 Executing middlewareTwo
2019/03/25 09:16:32 Executing finalHandler
2019/03/25 09:16:32 Executing middlewareTwo again
2019/03/25 09:16:32 Executing finalHandler
2019/03/25 09:16:32 Executing middlewareOne again
2019/03/25 09:16:32 Executing middlewareTwo
2019/03/25 09:16:32 Executing finalHandler
2019/03/25 09:16:32 Executing middlewareTwo again
2019/03/25 09:16:32 Executing finalHandler
2019/03/25 09:16:32 Executing middlewareOne yupiii

为什么在middlewareTwo again之前打印middlewareOne again

1 个答案:

答案 0 :(得分:4)

让堆栈成为一棵树,更容易理解:

middlewareOne()
    middlewareTwo()
        finalHandler()
            return finalHandler
        return middlewareTwo

    middlewareTwo again()
        finalHandler()
             return finalHandler()
        return middlewareTwo again

    return middleware one

middlewareOne again()
...

为了完成middleware one并移至middleware one again,它需要middleware two才能返回,因为middleware two包含middleware two again,因此需要运行{在完成之前再次{1}}。