TimeTimer

TimeTimer

The Timer type represents a single event. When the Timer expires, the current time will be sent on C, unless the Timer was created by AfterFunc. A Timer must be created with NewTimer or AfterFunc.

type Timer struct {
    C <-chan Time
    // contains filtered or unexported fields
}

两种一定时间后的方式

select

下面select是一直阻塞的

func GoAfter1() {
	timer := time.NewTimer(time.Second)

	select {
	case <-timer.C:
		fmt.Println("时间到了,玩游戏")
	}

	// 函数下面能运行到吗?
	fmt.Println("上面阻塞了,所以最后才能到这")
}

改进

看下面的select运行几次

func GoAfter2() {
	timer := time.NewTimer(time.Second)

	go func() {
		// 看select运行几次
		select {
		case <-timer.C:
			fmt.Println("时间到了,玩游戏")
		}
	}()

	// 函数下面能当然能运行
	fmt.Println("所以最后才能到这")
	time.Sleep(time.Second * 3)
}

#代码输出
所以最后才能到这
时间到了,玩游戏
PASS
ok      go-newbase/time/timer-base      3.200s

加上for循环呢?

func GoAfter3() {
	timer := time.NewTimer(time.Second)

	go func() {
		// 看select运行几次
		for {
			select {
			case <-timer.C:
				fmt.Println("时间到了,玩游戏")
			}
		}
	}()

	// 函数下面能当然能运行
	fmt.Println("所以最后才能到这")
	time.Sleep(time.Second * 3)
}


#代码输出
所以最后才能到这
时间到了,玩游戏
PASS
ok      go-newbase/time/timer-base      3.207s

下面是实现一直运行,就需要重置定时器

func GoAfter4() {
	timer := time.NewTimer(time.Second)

	go func() {
		// 看select运行几次
		for {
			select {
			case <-timer.C:
				fmt.Println("时间到了,玩游戏")
				timer.Reset(time.Second)
			}
		}
	}()

	// 函数下面能当然能运行
	fmt.Println("所以最后才能到这")
	time.Sleep(time.Second * 3)
}

#代码输出
所以最后才能到这
时间到了,玩游戏
时间到了,玩游戏
时间到了,玩游戏
PASS
ok      go-newbase/time/timer-base      3.211s

Afterfunc形式

因为下面函数不是阻塞的,主线程退出,所以没执行

func AfterPrint() {
	time.AfterFunc(time.Second, func() {
		fmt.Println("时间已到,吃饭")
	})
}


# 代码输出
啥也没输出

更改能输出的

func AfterPrint() {
	time.AfterFunc(time.Second, func() {
		fmt.Println("时间已到,吃饭")
	})
	
	time.Sleep(time.Second * 2)
}

# 代码输出
时间已到,吃饭
PASS
ok      go-newbase/time/timer-base      2.207s

Ticker

一个自动收报机持有一个通道,它每隔一段时间就发送一个时钟的“滴答声”。

A Ticker holds a channel that delivers `ticks' of a clock at intervals.

type Ticker struct {
    C <-chan Time // The channel on which the ticks are delivered.
    // contains filtered or unexported fields
}

官方文档用法

package main

import (
	"fmt"
	"time"
)

func main() {
	ticker := time.NewTicker(time.Second)
	defer ticker.Stop()
	done := make(chan bool)
	go func() {
		time.Sleep(3 * time.Second)
		done <- true
	}()
	for {
		select {
		case <-done:
			fmt.Println("Done!")
			return
		case t := <-ticker.C:
			fmt.Println("Current time: ", t)
		}
	}
}

# 代码输出
Current time:  2020-11-20 09:31:02.598433 +0800 CST m=+1.003463301
Current time:  2020-11-20 09:31:03.5981403 +0800 CST m=+2.003170601
Current time:  2020-11-20 09:31:04.5986842 +0800 CST m=+3.003714501
Done!

Api

func (t *Ticker) Reset(d Duration)

Reset stops a ticker and resets its period to the specified duration. The next tick will arrive after the new period elapses.

func (t *Ticker) Stop()

Stop turns off a ticker. After Stop, no more ticks will be sent. Stop does not close the channel, to prevent a concurrent goroutine reading from the channel from seeing an erroneous "tick".

posted @ 2020-12-13 15:34  maob  阅读(235)  评论(0编辑  收藏  举报