面试题答案
一键面试-
涉及步骤:
- 创建Context:一般使用
context.Background()
作为根Context开始,在HTTP处理中,会从http.Request
中获取Context
,如ctx := r.Context()
。 - 传递Context:将
Context
作为参数传递给各个需要控制生命周期或处理错误的子函数。 - 检查错误:在子函数中,通过
ctx.Err()
检查Context
是否被取消或超时,如果ctx.Err() != nil
,根据错误类型处理错误,比如返回特定错误信息。 - 取消操作:如果需要主动取消操作,可使用
context.WithCancel
创建一个可取消的Context
,在合适的时机调用取消函数来通知子函数停止操作。
- 创建Context:一般使用
-
代码结构和Context传递方式示例:
package main
import (
"context"
"fmt"
"net/http"
)
// 模拟子函数1
func subFunction1(ctx context.Context) error {
select {
case <-ctx.Done():
return ctx.Err()
default:
// 正常业务逻辑
fmt.Println("subFunction1 is running")
return nil
}
}
// 模拟子函数2
func subFunction2(ctx context.Context) error {
select {
case <-ctx.Done():
return ctx.Err()
default:
// 正常业务逻辑
fmt.Println("subFunction2 is running")
return nil
}
}
// HTTP处理函数
func httpHandler(w http.ResponseWriter, r *http.Request) {
ctx := r.Context()
// 调用子函数1
if err := subFunction1(ctx); err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
// 调用子函数2
if err := subFunction2(ctx); err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
w.Write([]byte("Success"))
}
func main() {
http.HandleFunc("/", httpHandler)
fmt.Println("Server is running on http://localhost:8080")
http.ListenAndServe(":8080", nil)
}
在上述代码中,httpHandler
从http.Request
获取Context
,然后将其传递给subFunction1
和subFunction2
。子函数通过ctx.Done()
通道监听Context
的取消信号,并在接收到取消信号时返回相应错误,httpHandler
根据子函数返回的错误进行处理。