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

errgroup สำหรับจัดการข้อผิดพลาดพร้อมกัน

ใช้งาน golang.org/x/sync/errgroup ในทางปฏิบัติ

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

ปัญหาของโกโรทีนและข้อผิดพลาด

การเรียกใช้โกโรทีนด้วย go func() จะทิ้งค่าที่ส่งคืน รวมถึงข้อผิดพลาดด้วย คุณต้องมีกลไกเพิ่มเติม (ช่องสัญญาณและ WaitGroup) เพื่อรวบรวมค่าเหล่านั้น errgroup ช่วยให้เรื่องนี้ง่ายขึ้น

golang.org/x/sync/errgroup

errgroup.Group เรียกใช้โกโรทีนและรวบรวมข้อผิดพลาด Wait() จะบล็อกจนกว่าโกโรทีนทั้งหมดจะทำงานเสร็จ และส่งคืนข้อผิดพลาดแรกที่ไม่ใช่ nil

var g errgroup.Group
g.Go(func() error { return fetchUsers() })
g.Go(func() error { return fetchOrders() })
if err := g.Wait(); err != nil {
    log.Fatal(err)
}

errgroup.WithContext

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

g, ctx := errgroup.WithContext(context.Background())
g.Go(func() error { return doWork(ctx) })
g.Go(func() error { return doOtherWork(ctx) })
err := g.Wait()

การรวบรวมผลลัพธ์ควบคู่กับข้อผิดพลาด

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

results := make([]Result, len(items))
for i, item := range items {
    i, item := i, item
    g.Go(func() error {
        r, err := process(ctx, item)
        if err != nil { return err }
        results[i] = r
        return nil
    })
}
if err := g.Wait(); err != nil { return err }

g.SetLimit (Go 1.20 ขึ้นไป)

g.SetLimit(n) จำกัดจำนวนโกโรทีนที่ทำงานพร้อมกัน — ทำหน้าที่เหมือนเซมาฟอร์แบบฝังในโค้ดโดยไม่ต้องใช้ช่องสัญญาณแยกต่างหาก

g.SetLimit(10) // at most 10 goroutines at once
for _, item := range items {
    g.Go(func() error { return process(item) })
}

g.TryGo

g.TryGo(f) จะเริ่มโกโรทีนก็ต่อเมื่อขีดจำกัด (ที่กำหนดโดย SetLimit) อนุญาต หากไม่สามารถเริ่มได้จะส่งคืน false

ส่งคืนเฉพาะข้อผิดพลาดแรก

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

var mu sync.Mutex
var errs []error
g.Go(func() error {
    if err := doWork(); err != nil {
        mu.Lock(); errs = append(errs, err); mu.Unlock()
    }
    return nil
})

ความแตกต่างจาก sync.WaitGroup

WaitGroup ติดตามการทำงานเสร็จสิ้น ส่วน errgroup ติดตามการทำงานเสร็จสิ้นและรวบรวมข้อผิดพลาดด้วย ควรใช้ errgroup เมื่อความล้มเหลวของโกโรทีนใด ๆ ควรถูกรายงาน

การส่งต่อการยกเลิกของบริบท

เมื่อใช้ errgroup.WithContext การยกเลิกของบริบทที่สร้างต่อจะแจ้งให้โกโรทีนอื่น ๆ หยุดทำงานทั้งหมด ซึ่งคล้ายกับความหมายที่ยกเลิกเมื่อเกิดข้อผิดพลาดแรก

การทดสอบโค้ด errgroup

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

ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
defer cancel()
g, ctx := errgroup.WithContext(ctx)

ทางเลือกแทนเซมาฟอร์

ก่อนมี SetLimit (Go < 1.20) ให้ใช้ช่องสัญญาณแบบมีบัฟเฟอร์เป็นเซมาฟอร์ภายในโกโรทีนแต่ละตัวเพื่อให้ได้ผลลัพธ์แบบเดียวกัน

ตรวจสอบอย่างรวดเร็ว

errgroup.WithContext ส่งคืนอะไรที่ errgroup.Group แบบธรรมดาไม่ส่งคืน

สรุป: errgroup

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

  • g.Go(func() error) — เริ่มทำงานและรวบรวมข้อผิดพลาดแรก
  • g.Wait() — บล็อกจนกว่าทั้งหมดจะเสร็จสิ้น และส่งคืนข้อผิดพลาดแรก
  • WithContext — บริบทถูกยกเลิกเมื่อเกิดข้อผิดพลาดแรก
  • g.SetLimit(n) — จำกัดจำนวนโกโรทีนที่ทำงานพร้อมกัน (Go 1.20 ขึ้นไป)

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

บทเรียน “errgroup สำหรับจัดการข้อผิดพลาดพร้อมกัน” ฟรีหรือไม่

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

คุณจะเรียนรู้อะไรในบทเรียน “errgroup สำหรับจัดการข้อผิดพลาดพร้อมกัน”

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

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

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

บทเรียน “errgroup สำหรับจัดการข้อผิดพลาดพร้อมกัน” ใช้เวลานานแค่ไหน

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

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

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

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

  1. รูปแบบไปป์ไลน์และขั้นตอน
  2. errgroup สำหรับจัดการข้อผิดพลาดพร้อมกัน
  3. รูปแบบเซมาฟอร์
  4. การตรวจจับการรั่วไหลและการยกเลิก
← กลับไปที่ Go Academy