3

    标准库的Timer允许用户自定义超时逻辑(适用于单个chanel读写超时、select处理多个chanel超时等情况)。

  • 注意:Timer是一次性触发,和一定时间间隔触发的Ticker不同(类似JavaScript里的settimeout和setinterval的区别)。

Timer常见的创建方式如下:

  • t := time.NewTimer(d)
  • t := time.AfterFunc(d, f)
  • c := time.After(d)
    (注:d代表定时时间;f代表触发的动作;c就是chanel)

time.NewTimer

举个实际例子来说明这个API的用法:

package main

import (
    "fmt"
    "time"
)

func main() {
    timer := time.NewTimer(3 * time.Second)
    fmt.Printf("%T\n", timer)
    //打印一下系统的当前时间
    fmt.Println(time.Now())
    //此处等待chanel中的数值 会阻塞3s
    ch2 := timer.C
    fmt.Println(<-ch2)
}

运行结果如下:

*time.Timer
2022-05-27 18:15:59.740761 +0800 CST m=+0.000224834
2022-05-27 18:16:02.741175 +0800 CST m=+3.000731959

另外 在计时器到期之前我们还可以取消这个计时器,比如下面的代码例子:

package main

import (
    "fmt"
    "time"
)

func main() {
    //    新建一个计时器
    timer2 := time.NewTimer(5 * time.Second)
    //开始协程处理触发后的事件
    go func() {
        <-timer2.C
        fmt.Println("timer2 has been completed")
    }()

    time.Sleep(3 * time.Second)
    flag := timer2.Stop()
    if flag {
        fmt.Println("Timer2 was stopped")
    }
}

运行结果是:
Timer2 was stopped

time.After()

本质上就是NewTimer(d).C,作用就是在持续时间d之后返回通道C,C中存储的是d后的时间。
func After(d Duration) <- chan Time
注:如果有效率问题需要考虑,官方文档建议使用NewTimer来替代。 如果当前计时器不被需要了,也可以用Stop()停止。

参考:bilibili


LiberHome
409 声望1.1k 粉丝

有问题 欢迎发邮件 📩 liberhome@163.com