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)
}