go语言time包里有各种跟时间有关的结构和函数,定时器NewTicker是设定每隔多长时间触发的,是连续触发,而计时器NewTimer是等待多长时间触发的,只触发一次,两者是不同的。等待时间函数AfterFunc是在After基础上加了一个回调函数,是等待时间到来后在另外一个goroutine协程里调用。
下面使用例子:
// test.go
package main
import (
"fmt"
"time"
)
func Readf(ch chan int) {
fmt.Println("子协程开始执行!")
// 创建一个定时器NewTicker, 每隔2秒触发一次,类似于闹钟
timer := time.NewTicker(time.Second * 2)
//time.NewTimer(time.Second * 2)这种是创建一个计时器,2秒后只触发一次。
//time.After相当于是对NewTimer的封装,如下面所示。
num := 5
for {
select {
//case <-time.After(time.Second * 2)://这样就是等待2秒时间到,只触发一次
case <-timer.C: //因为上边是用NewTicker创建的定时器,所以每隔2秒都会触发
ch <- num
num--
if num < 0 { //直到小于0,则退出
goto end
}
}
}
end:
fmt.Println("子协程退出!")
}
func F() {
fmt.Println("主程序开始执行!")
}
func main() {
ch := make(chan int)
go Readf(ch)
//time.AfterFunc()函数是在 time.After 基础上增加了到时的回调函数,方便使用,是在另外一个goroutine协程调用
//第2个参数是一个回调函数指针,这里是将回调函数显式创建在外部,传递过来函数名,无法使用内部变量。
time.AfterFunc(time.Second*1, F)
for {
v := <-ch //从管道里读取数据
fmt.Println(v)
if v == 0 {
break
}
}
//这里第2个参数是一个匿名函数,可以调用内部变量,相当于一个闭包。
time.AfterFunc(time.Second*2, func() {
fmt.Println("给主程序管道发送退出消息!")
ch <- 88
})
fmt.Println("主程序退出", <-ch) //等待退出消息
}