1. 程式人生 > 其它 >每日一抄 Go語言使用通道響應計時器事件

每日一抄 Go語言使用通道響應計時器事件

package main

import (
	"fmt"
	"time"
)

/*
Go語言中,time包提供了計時器的封裝。由於Go語言中的通道和goroutine的設計,定時任務可以在goroutine
中通過同步的方式完成,也可以通過在goroutine中非同步回撥完成,這裡將展示這兩個方法
*/

//一段時間之後 (time.After)
//延遲迴調

func main() {
	//宣告一個退出用的通道
	exit := make(chan int)

	//列印開始
	fmt.Println("start")

	//過一秒後呼叫匿名函式
	//傳入等待的時間和一個回撥,回撥使用一個匿名函式,在時間到達後,匿名函式會在另一個goroutine中被呼叫
	time.AfterFunc(time.Second, func() {
		//一秒後列印結果
		fmt.Println("這就是列印的結果")
		//通知main的goroutine已經結束
		//這裡往通道中寫入,代表需要退出。
		exit <- 0
	})
	
	//這裡很重要,代表main的goroutine被阻塞(因為此時通道中是沒有值可以拿出來的),要等待一秒後
	//第三十行被執行,exit通道中有資料後才能繼續執行
	<-exit

}

time.AfterFunc() 函式是在 time.After 基礎上增加了到時的回撥,方便使用。

而 time.After() 函式又是在 time.NewTimer() 函式上進行的封裝,下面的例子展示如何使用 timer.NewTimer() 和 time.NewTicker()。

package main

import (
	"fmt"
	"time"
)

/*
計時器(Timer)的原理和倒計時鐘類似,都是給定多少時間後觸發。打點器(Ticker)的原理和鐘錶類似,鐘錶每到整點就會觸發
這兩種方法建立後會返回time.Ticker物件和time.Timer物件,裡面通過一個C成員,型別是隻能接收時間通道(<- chan Time)
使用這個通道就可獲得時間觸發的通知
*/

//下面程式碼建立一個打點器。每500ms觸發一起;建立一個計時器2s後觸發,只觸發一次

//計時器

func main() {
	//建立一個打點器每500ms觸發一次
	ticker := time.NewTicker(time.Millisecond * 500)

	//建立一個計時器,2s後觸發
	stopper := time.NewTimer(time.Second * 2)

	//宣告計數變數
	var i int

	//不斷檢查通道情況
	for {
		//Multiplex chan
		select {
		//計時器觸發
		case <-stopper.C:
			fmt.Println("stop")
			//跳出迴圈
			goto StopHere
		//打點器觸發
		case <-ticker.C:
			//記錄觸發了多少次
			i++
			fmt.Println("tick", i)
		}

	}
	//退出的標籤,使用goto跳轉
StopHere:
	fmt.Println("done")
}

/*
type Timer struct {
	C <-chan Time
	r runtimeTimer
}
*/