Golang time tick

Golang time tick使用

golang 中,After(d) 是只等待一次 d 的时长,并在这次等待结束后将当前时间发送到通道。Tick(d) 则是间隔地多次等待,每次等待 d 时长,并在每次间隔结束的时候将当前时间发送到通道。

因为 Tick() 也是在等待结束的时候发送数据到通道,所以它的返回值是一个 channel,从这个 channel 中可读取每次等待完时的时间点。

Golang time tick详解

语法

func tick(d Duration) <-chan Time

时长

参数 描述
d 时长

说明

tick() 函数接受一个时长 d,然后它 tick() 等待 d 时长,等待时间到后,将等待完成时所处时间点写入到 channel 中并返回这个只读 channel。

Golang time tick典型用法

time tick触发

package main import ( "fmt" "time" ) func main() { fmt.Println("嗨客网(www.haicoder.net)") select { case <-time.Tick(2 * time.Second): fmt.Println("2 second over:", time.Now().Second()) case <-time.After(7 * time.Second): fmt.Println("5 second over, timeover", time.Now().Second()) return } }

程序运行后,输出如下图所示:

44_Go语言time tick使用.png

上面的示例,在等待 2 秒之后,就会因为读取到了 time.Tick() 的通道数据而终止,因为 select 并未在循环内。

time tick设置超时

package main import ( "fmt" "time" ) func main() { fmt.Println("嗨客网(www.haicoder.net)") for { select { case <-time.Tick(2 * time.Second): fmt.Println("2 second over:", time.Now().Second()) case <-time.After(7 * time.Second): fmt.Println("5 second over, timeover", time.Now().Second()) return } } }

程序运行后,输出如下图所示:

45_Go语言time tick使用.png

如果 select 在循环内,第二个 case 将永远选择不到。因为每次 select 轮询中,第一个 case 都因为 2 秒而先被选中,使得第二个 case 的评估总是被中断。进入下一个 select 轮询后,又会重新开始评估两个 case,分别等待 2 秒和 7 秒。

time tick设置超时

package main import ( "fmt" "time" ) func main() { fmt.Println("嗨客网(www.haicoder.net)") tick := time.Tick(1 * time.Second) after := time.After(7 * time.Second) fmt.Println("start second:",time.Now().Second()) for { select { case <-tick: fmt.Println("1 second over:", time.Now().Second()) case <-after: fmt.Println("7 second over:", time.Now().Second()) return } } }

程序运行后,输出如下图所示:

46_Go语言time tick使用.png

上面不正常执行的原因是因为每次 select 都会重新评估这些表达式。如果把这些表达式放在 select 外面,则正常。

将 time.Tick() 和 time.After() 放在 for…select 的外面,使得 select 每次只评估通道是否可读、可写事件,而不会重新执行 time.Tick() 和 time.After(),使得它们重新进入计时状态。

Golang time tick使用总结

在 golang 中,After(d) 是只等待一次 d 的时长,并在这次等待结束后将当前时间发送到通道。Tick(d) 则是间隔地多次等待,每次等待 d 时长,并在每次间隔结束的时候将当前时间发送到通道。

因为 Tick() 也是在等待结束的时候发送数据到通道,所以它的返回值是一个 channel,从这个 channel 中可读取每次等待完时的时间点。