Go 定時器/延時觸發器

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
    }
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章