1. time.After
假設業務中需調用服務接口A,要求超時時間爲5秒,那麼如何優雅、簡潔的實現呢?
可以採用select
+time.After
的方式,十分簡單適用的實現。
package main
import (
"fmt"
"time"
)
//發送者
func sender(c chan int) {
for i := 0; i < 20; i++ {
c <- i
if i >= 5 {
time.Sleep(time.Second * 7)
} else {
time.Sleep(time.Second)
}
}
}
func main() {
c := make(chan int)
go sender(c)
timeout := time.After(time.Second * 3)
for {
select {
case d := <-c:
fmt.Println(d)
case <-timeout:
fmt.Println("執行定時操作任務")
case dd := <-time.After(time.Second * 3):
fmt.Println(dd.Format("2006-01-02 15:04:05"), "執行超時動作")
}
fmt.Println("for end")
}
}
2. time.NewTimer
NewTimer 創建一個 Timer,它會在最少過去時間段 d 後到期,向其自身的 C 字段發送當時的時間
t.Reset()需要重置Reset 使 t 重新開始計時
package main
import (
"fmt"
"time"
)
func main() {
t := time.NewTimer(time.Second * 2)
ch := make(chan bool)
go func(t *time.Timer) {
defer t.Stop()
for {
select {
case <-t.C:
fmt.Println("timer running....")
// 需要重置Reset 使 t 重新開始計時
t.Reset(time.Second * 2)
case stop := <-ch:
if stop {
fmt.Println("timer Stop")
return
}
}
}
}(t)
time.Sleep(10 * time.Second)
ch <- true
close(ch)
time.Sleep(1 * time.Second)
}
3. time.NewTicker
NewTicker 返回一個新的 Ticker,該 Ticker 包含一個通道字段,並會每隔時間段 d 就向該通道發送當時的時間。它會調整時間間隔或者丟棄 tick 信息以適應反應慢的接收者。如果d <= 0會觸發panic。
ticker.Stop()關閉該 Ticker 可以釋放相關資源。
package main
import (
"fmt"
"time"
)
func main() {
ticker := time.NewTicker(2 * time.Second) // 新建一個Ticker
ch := make(chan bool)
go func(ticker *time.Ticker) {
defer ticker.Stop() // 停止Ticker
for {
select {
case <-ticker.C: // Ticker.C 的封裝
fmt.Println("Ticker running...")
case stop := <-ch:
if stop {
fmt.Println("Ticker Stop")
return
}
}
}
}(ticker)
time.Sleep(10 * time.Second)
ch <- true
close(ch)
}