ฟังก์ชัน time.Sleep ใน Go เราใช้เพื่อหน่วงเวลาให้ goroutine ที่ฟังก์ชันนี้รันหยุดทำงานไปเป็นจำนวนเวลาเท่าที่เราใส่ให้ฟังก์ชันตอนเรียกใช้งาน
แต่ถ้าเกิดเราต้องการให้ time.Sleep นั้นถูกยกเลิกการ Sleep ก่อนเวลาที่เราส่งให้มัน เราต้องสร้าง Sleep ฟังก์ชันขึ้นมาเองแบบที่ยกเลิกได้
สิ่งที่ช่วยได้ก็คือ type Timer ซึ่งเรากำหนดค่า duration ให้กับมันแล้วมันก็จะส่ง signal ออกมาที่ channel C
ซึ่งเป็น field นึงของ type Timer นั่นเอง
ดังนั้น ถ้าเวลาผ่านไปยังไม่ถึง duration ที่กำหนด แล้วเราไปพยายามเอาค่าออกมาจาก C
มันก็จะหยุดเหมือน time.Sleep นั่นเอง
โค้ดแบบนี้ ทำหน้าที่เหมือน time.Sleep
func mySleep(d time.Duration) {
timer := time.NewTimer(d)
<-timer.C
}
สิ่งที่ Timer มีมากกว่า Sleep คือมันมี method Stop
ให้ยกเลิก Timer ก่อนเวลาที่กำหนดได้
ต่อไปเราจะทำให้ฟังก์ชัน SleepContext ของเรานั้นรับ context.Context เข้ามาด้วย เพื่อใช้เป็น signal ว่าเมื่อ context นั้นทำงานเสร็จ หรือยกเลิกแล้ว นั้นเราก็จะเรียก timer.Stop ด้วยนั่นเอง
โค้ดของ SleepContext ที่จะ Sleep และยกเลิกถ้า ctx นั้นถูกยกเลิกหรือ Done เรียบร้อยแล้ว
func SleepContext(ctx context.Context, d time.Duration) {
timer := time.NewTimer(d)
select {
case <-ctx.Done():
timer.Stop()
case <- timer.C:
}
}
เราใช้ select statment เพื่อรอรับค่าจากทั้ง ctx.Done() หรือ timer.C อะไรมีค่ามาก่อนก็จบการทำงานของฟังก์ชัน แต่ถ้า ctx.Done() ก่อนก็ไม่ลืมที่จะยกเลิก timer ไปด้วย เพื่อไม่ให้มันยังทำงานทำให้เกิด memory leak อยู่จนกว่าจะหมดเวลา
ขอฝาก Buy Me a Coffee
สำหรับท่านใดที่อ่านแล้วชอบโพสต์ต่างๆของผมที่นี่ ต้องการสนับสนุนค่ากาแฟเล็กๆน้อยๆ สามารถสนับสนุนผมได้ผ่านทาง Buy Me a Coffee คลิ๊กที่รูปด้านล่างนี้ได้เลยครับ
Top comments (0)