Go
能夠藉助 time.After/time.Ticker
來實現延遲/定時觸發器,主要原理是藉助無緩衝channel
無數據時讀取操做會阻塞當前協程,Go
會在給定的時間後向channel
中寫入一些數據(當前時間),故阻塞的協程能夠恢復運行,達到延遲或定時執行的功能。code
time.After(d Duration)
好像不如直接用 time.Sleep(d Duration)
舒服,但存在即合理,time.After(d Duration)
的強大之處在因而基於channel
的,能夠在不一樣的協程間同步傳遞。orm
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()
方法it
func main() { // 建立一個計時器 timeTickerChan := time.Tick(time.Second * 2) for { fmt.Println(time.Now().Format("2006-01-02 15:04:05")) <-timeTickerChan } }