0Pricing
Go Academy · บทเรียน

WithDeadline และ WithValue

กำหนดเส้นตายแบบสัมบูรณ์และส่งค่าที่มีขอบเขตตามคำขอ

WithDeadline และ WithValue เป็นบทเรียน Go Academy ฟรีบน CoddyKit นี่คือบทเรียนที่ 3 จากทั้งหมด 4 บทเรียน คุณสามารถอ่านบทเรียนทั้งหมดด้านล่างฟรี — จากนั้นลองปฏิบัติด้วยตัวคุณเองในเบราว์เซอร์พร้อมตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7 บทเรียนนี้เป็นส่วนหนึ่งของเส้นทางการเรียน Go Academy และความก้าวหน้าของคุณจะซิงค์ข้ามเว็บและแอป CoddyKit คอร์ส Go Academy มีบทเรียนทั้งหมด 4 บทเรียน

context.WithDeadline

WithDeadline สร้างบริบทที่ยกเลิกเมื่อถึงเวลาสัมบูรณ์ที่กำหนด หากบริบทแม่มีกำหนดเวลาสิ้นสุดที่เร็วกว่านั้นอยู่แล้ว กำหนดเวลาของบริบทแม่จะมีผลเหนือกว่า

deadline := time.Now().Add(10 * time.Second)
ctx, cancel := context.WithDeadline(parent, deadline)
defer cancel()

WithTimeout เทียบกับ WithDeadline

WithTimeout(parent, d) เทียบเท่ากับ WithDeadline(parent, time.Now().Add(d)) ให้ใช้ WithDeadline เมื่อมีเวลาหมดอายุแบบสัมบูรณ์ (เช่น จากส่วนหัว RPC ขาเข้า)

การอ่านกำหนดเวลา

ตรวจสอบกำหนดเวลาของบริบทใด ๆ ด้วย ctx.Deadline() ค่าบูลีนระบุว่ามีกำหนดเวลาหรือไม่

if deadline, ok := ctx.Deadline(); ok {
    fmt.Println("expires at:", deadline)
}

context.WithValue

WithValue ผูกคู่คีย์-ค่าเข้ากับบริบท โค้ดฝั่งถัดไปดึงค่าดังกล่าวด้วย ctx.Value(key)

type ctxKey string
const userKey ctxKey = "user"

ctx := context.WithValue(parent, userKey, currentUser)

func getUser(ctx context.Context) *User {
    u, _ := ctx.Value(userKey).(*User)
    return u
}

การป้องกันคีย์ชนกัน

ใช้ชนิดเฉพาะแพ็กเกจที่ไม่ส่งออกสำหรับคีย์ เพื่อป้องกันการชนกันระหว่างแพ็กเกจ อย่าใช้ชนิดในตัว (string, int) เป็นคีย์บริบทโดยตรง

// Bad: string key can collide
ctx = context.WithValue(ctx, "user", u)
// Good: package-scoped type
type userKeyType struct{}
ctx = context.WithValue(ctx, userKeyType{}, u)

สิ่งที่ควรจัดเก็บในบริบท

จัดเก็บเฉพาะค่าที่อยู่ในขอบเขตคำขอและข้ามขอบเขตเอพีไอ เช่น รหัสติดตาม โทเค็นการยืนยันตัวตน และรหัสคำขอ อย่าจัดเก็บอาร์กิวเมนต์ฟังก์ชันที่เป็นตัวเลือกหรือสถานะที่เปลี่ยนแปลงได้

ประสิทธิภาพของ WithValue

ctx.Value ค้นหาแบบเชิงเส้นย้อนขึ้นไปตามสายโซ่บริบท หลีกเลี่ยงการจัดเก็บหลายค่าในแต่ละบริบท หากมีหลายค่า ให้รวมค่าเหล่านั้นไว้ในโครงสร้างเดียว

type RequestMeta struct {
    UserID  int
    TraceID string
}
type metaKey struct{}
ctx = context.WithValue(ctx, metaKey{}, RequestMeta{...})

การส่งต่อค่าผ่านมิดเดิลแวร์

มิดเดิลแวร์ HTTP เป็นจุดมาตรฐานสำหรับแนบข้อมูลเมตาของคำขอเข้ากับบริบท และดึงข้อมูลดังกล่าวในตัวจัดการ:

func Auth(next http.Handler) http.Handler {
    return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
        user := authenticate(r)
        ctx := context.WithValue(r.Context(), userKey, user)
        next.ServeHTTP(w, r.WithContext(ctx))
    })
}

r.WithContext

แทนที่บริบทของคำขอ HTTP ด้วย r.WithContext(ctx) การดำเนินการนี้จะสร้างสำเนาแบบตื้นของคำขอพร้อมบริบทใหม่ โดยไม่แก้ไขคำขอเดิม

การส่งต่อกำหนดเวลา

เมื่อเกตเวย์กำหนดเวลาในบริบทและส่งคำขอต่อไปยังบริการถัดไป บริการทั้งหมดที่รับบริบทจะเคารพกำหนดเวลานั้นโดยอัตโนมัติ โดยไม่ต้องมีตรรกะหมดเวลาโดยเฉพาะ

สายโซ่ของบริบท

แต่ละ WithValue, WithCancel และ WithTimeout จะห่อบริบทแม่ไว้ในโหนดใหม่ ctx.Value จะไล่ไปตามสายโซ่จนกว่าจะพบคีย์หรือถึงบริบทต้นทางที่คืนค่า nil

ตรวจสอบความเข้าใจอย่างรวดเร็ว

เหตุใดคีย์บริบทจึงควรเป็นชนิดเฉพาะแพ็กเกจที่ไม่ส่งออก?

สรุป: WithDeadline และ WithValue

ประเด็นสำคัญ:

  • WithDeadline ยกเลิกเมื่อถึงเวลาสัมบูรณ์ ส่วน WithTimeout ใช้เวลาแบบสัมพัทธ์
  • ctx.Deadline() ใช้อ่านกำหนดเวลา
  • ใช้ WithValue สำหรับข้อมูลเมตาที่อยู่ในขอบเขตคำขอ และใช้คีย์ที่มีชนิดและไม่ส่งออก
  • รวมหลายค่าไว้ในโครงสร้างเดียวเพื่อลดความลึกของสายโซ่

คำถามที่พบบ่อย

บทเรียน “WithDeadline และ WithValue” ฟรีหรือไม่

ใช่ — ข้อความเต็มของ “WithDeadline และ WithValue” ฟรีให้อ่านที่นี่บนเว็บ เพื่อปฏิบัติแบบโต้ตอบ (ตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7) และปลดล็อคส่วนที่เหลือของคอร์ส Go Academy ให้อัปเกรดเป็น CoddyKit PRO คอร์ส Go Academy มีบทเรียนทั้งหมด 4 บทเรียน

คุณจะเรียนรู้อะไรในบทเรียน “WithDeadline และ WithValue”

กำหนดเส้นตายแบบสัมบูรณ์และส่งค่าที่มีขอบเขตตามคำขอ คุณปฏิบัติ Go Academy ด้วยโค้ดที่ใช้งานได้จริงที่คุณเรียกใช้โดยตรงในเบราว์เซอร์ และติวเตอร์ AI ตลอด 24/7 ตอบคำถามของคุณขณะที่คุณไปผ่านบทเรียน

คุณต้องมีประสบการณ์ก่อนที่จะเริ่มเรียน Go Academy หรือไม่

ไม่จำเป็นต้องมีประสบการณ์มาก่อน Go Academy บน CoddyKit ออกแบบมาสำหรับผู้เริ่มต้นไปจนถึงผู้เรียนขั้นสูง คุณสามารถเริ่มต้นที่นี่หรือเริ่มจากตัวแรกและเรียนด้วยความเร็วของคุณเอง นี่คือบทเรียนที่ 3 จากทั้งหมด 4 บทเรียน

บทเรียน “WithDeadline และ WithValue” ใช้เวลานานแค่ไหน

บทเรียน CoddyKit ส่วนใหญ่ใช้เวลาประมาณ 5–10 นาที แต่ละบทเรียนจึงสั้นและเป็นแบบโต้ตอบ คุณสามารถก้าวหน้าอย่างต่อเนื่องและกลับมาเรียนต่อจากตรงที่เพิ่งหยุดบนเว็บและแอปได้เลย

ฉันเขียนและรันโค้ดในบทเรียน Go Academy นี้ได้ไหม

ได้ บทเรียน Go Academy ทุกบทมีตัวแก้ไขโค้ดในตัว คุณจึงเขียนและรันโค้ดจริงได้เลยในเบราว์เซอร์ และได้รับข้อเสนอแนะจาก AI ในทันที — ไม่ต้องติดตั้งในเครื่องของคุณ

บทเรียนทั้งหมดในหลักสูตรนี้

  1. เหตุผลที่มี context.Context
  2. WithCancel และ WithTimeout
  3. WithDeadline และ WithValue
  4. Context ในการเรียกใช้ HTTP และฐานข้อมูล
← กลับไปที่ Go Academy