Go
可以藉助 time.After/time.Ticker
來實現延遲/定時觸發器,主要原理是藉助無緩衝channel
無數據時讀取操作會阻塞當前協程,Go
會在給定的時間後向channel
中寫入一些數據(當前時間),故阻塞的協程可以恢復運行,達到延遲或定時執行的功能。
延遲執行
time.After(d Duration)
好像不如直接用 time.Sleep(d Duration)
舒服,但存在即合理,time.After(d Duration)
的強大之處在於是基於channel
的,可以在不同的協程間同步傳遞。
package main
import (
"time"
"fmt"
)
func main() {
fmt.Println(time.Now().Format("2006-01-02 15:04:05"))
// create a nobuf channel and a goroutine `timer` will write it after 2 seconds
timeAfterTrigger = time.After(time.Second * 2)
// will be suspend but we have `timer` so will be not deadlocked
curTime, _ := <-timeAfterTrigger
// print current time
fmt.Println(curTime.Format("2006-01-02 15:04:05"))
}
定時執行
time.Ticker
的使用分兩種場景:執行幾次後退出 和 循環執行不退出,執行幾次就退出的話我們需要需要回收 time.Ticker
。
執行若干次後退出需清理計時器
func main() {
// 創建一個計時器
timeTicker := time.NewTicker(time.Second * 2)
i := 0
for {
if i > 5 {
break
}
fmt.Println(time.Now().Format("2006-01-02 15:04:05"))
i++
<-timeTicker.C
}
// 清理計時器
timeTicker.Stop()
}
循環執行不需要清理的話可以用更簡便的time.Tick()
方法
func main() {
// 創建一個計時器
timeTickerChan := time.Tick(time.Second * 2)
for {
fmt.Println(time.Now().Format("2006-01-02 15:04:05"))
<-timeTickerChan
}
}