package main import ( "fmt" "time" ) var location, _ = time.LoadLocation("Asia/Shanghai") var layout = "2006-01-02 15:04:05" // GetDateTime 获取当前时间的日期时间字符串 // @return string 日期时间字符串 func GetDateTime() string { sec := time.Now().In(location).Unix() return time.Unix(sec, 0).In(location).Format(layout) } func main() { timer := time.NewTimer(time.Second * 3) // 创建Timer,设置3秒后执行,这里并不会发生阻塞。 fmt.Printf("[%+v] 等待执行 \n", GetDateTime()) // 停止并重置Timer if !timer.Stop() { <-timer.C // 清空管道(Timer的管道长度为1,只要读出数据就是清空了) } timer.Reset(time.Second * 3) channel := <-timer.C // 重要提醒:这里会发生阻塞,阻塞时间长短由设置的延迟时间决定。 fmt.Printf("[%+v] 正在执行 \n", channel.In(location).Format(layout)) time.Sleep(time.Second * 2) fmt.Printf("[%+v] 完成执行 \n", GetDateTime()) } //========== 总结 ==========// // 1、Go里的Timer相当于JavaScript里的setTimeout(),就是把一些任务延迟执行,例如订单状态的变更,如果用户一直没有支付,订单不 // 可能一直保持在待支付状态,肯定需要在过了一定时间后将订单状态改为已失效,这时就可以使用Timer,具体做法就是在创建订单的 // 同时创建对应的Timer来延迟更新订单状态,如果超时了用户仍未支付就将订单状态改为已失效。 // 2、Timer的本质是管道的读写,time.NewTimer()就是把执行任务时间(延迟)写入管道,开发者从管道读到数据后实现自己的逻辑即可。 // 3、Timer提供了Stop()方法和Reset()方法来实现停止和重置,两者一般配对使用避免出现deadlock问题。 // 4、如果调用timer.Stop()停止了Timer还从timer.C管道读取数据就会发生deadlock。
Copyright © 2024 码农人生. All Rights Reserved