Иногда нужно запускать какую-то функцию с регулярным интервалом — например, проверку состояния, отправку метрик или повторный запрос. В Go это делается через time.Ticker.
package main import ( "fmt" "time" ) func main() { tick := time.NewTicker(time.Millisecond * 100) // создаем тикер, содержащий в канал, в который будут записаны значения каждый duration. stop := time.NewTimer(time.Second * 1) // создаем таймер, который сработает через 2 секунды defer tick.Stop() // освободим ресурсы, которые тикер создает в фоне, при завершении работы функции. // В данном примере вызов Stop не критичен, ведь завершится весь main итак и ресурсы освободятся. i := 0 for { select { case <-stop.C: fmt.Println("Stop work. Timeout is reached.") return case <-tick.C: doWork(i) i++ } } } func doWork(i int) { fmt.Printf("Tick number: %d\n", i) }
Как это работает:
-
time.NewTicker(duration)
создаёт канал, в который через каждыеduration
будет поступать значение. -
time.NewTimer(duration)
— запускает таймер, который сработает один раз через заданное время. -
Через
select
слушаем оба канала:-
Если пришёл сигнал от
stop.C
, завершение работы. -
Если пришёл сигнал от
tick.C
, вызываемdoWork
.
-
Если пришёл сигнал от
Важно:
-
Ticker запускает фоновые горутины, поэтому его нужно остановить, когда он больше не нужен (
tick.Stop()
). -
В реальных приложениях можно использовать
context.WithTimeout
илиcontext.WithCancel
для более гибкого управления временем выполнения.