penglongli / blog

18 stars 1 forks source link

golang 的 Timer 和 Ticker #56

Open penglongli opened 6 years ago

penglongli commented 6 years ago

Timer 的使用一般来说有如下几点:

注意 Timer 只执行一次,Ticker 可以循环执行。类似于 js 中的 setTimeout 与 setInterval 的区别。

Timer 例子

定时多久后执行某个方法

func main() {
    _ = time.AfterFunc(2 * time.Second, hello)

    ch := make(chan os.Signal)
    signal.Notify(ch, syscall.SIGINT, syscall.SIGTERM)

    // Block util a signal is received
    log.Println(<-ch)

}

func hello() {
    fmt.Println("Hello World!")
}

上述例子在 2s 后执行 hello() 方法。

对操作超时处理

func main() {
    c := make(chan int)
    go func() {
        hello()
        c <- 1
    }()

    select {
    case <- c:
    case <- time.After(2 * time.Second):
        fmt.Println("Timeout")
    }
}

func hello() {
    // 模拟业务执行时间
    time.Sleep(5 * time.Second)
    fmt.Println("Hello World!")
}

从上边可以看到,hello() 方法执行超过了 5s,而 timeout 设置的时间是 2s。在超过 2s 后,直接输出 Timeout 然后结束。

上边的代码也可以变种为如下:

func main() {
    c := make(chan int)
    go func() {
        hello()
        c <- 1
    }()

    timer := time.NewTimer(2 * time.Second)
    select {
    case <- c:
    case <- timer.C:
        fmt.Println("Timeout")
    }
}

func hello() {
    // 模拟业务执行时间
    time.Sleep(5 * time.Second)
    fmt.Println("Hello World!")
}

Ticker 例子

Ticker 相比于 Timer 可以循环执行,例子如下:

package main

import (
    "time"
    "fmt"
)

func main() {

    ticker := time.NewTicker(2 * time.Second)

    go func() {
        for t := range ticker.C {
            fmt.Println("Tick at", t)
        }
    }()

    time.Sleep(10 * time.Second)
    ticker.Stop()
    fmt.Println("Stopped")
}

常见的应用场景比如数据库链接断掉重连等,后边补例子