Поток выполнения промежуточного программного обеспечения - PullRequest
1 голос
/ 25 марта 2019

Я не могу понять поток выполнения этого кода:

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 Ответ

4 голосов
/ 25 марта 2019

Давай сделаем стек деревом, это легче понять:

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, для завершения необходимо еще раз запустить middleware two.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...