Тайм-ауты и тикеры
Использование time.After и time.Tick с select
«Тайм-ауты и тикеры» — бесплатный урок Go Academy на CoddyKit. Это урок 2 из 4. Ты можешь прочитать весь урок бесплатно ниже — а потом практиковать его прямо в браузере с встроенным редактором кода и ИИ-репетитором 24/7. Это часть пути обучения Go Academy, и твой прогресс синхронизируется между веб-версией и приложением CoddyKit. Курс Go Academy содержит 4 уроков всего.
Зачем нужны тайм-ауты
Без тайм-аутов горутина, ожидающая медленный канал, может заблокироваться навсегда. Пакет time предоставляет средства для добавления управления по времени к операциям с каналами.
Однократный тайм-аут с помощью time.After
time.After(d) возвращает канал, из которого поступает значение по истечении периода d. Используйте его в варианте select, чтобы прервать ожидание.
select {
case res := <-ch:
fmt.Println(res)
case <-time.After(2 * time.Second):
fmt.Println("timed out")
}Повторяющиеся тайм-ауты с помощью time.NewTimer
Для повторно используемых таймеров применяйте time.NewTimer и вызывайте Reset после каждого использования. Вызывайте Stop, чтобы предотвратить утечку горутины таймера.
timer := time.NewTimer(5 * time.Second)
defer timer.Stop()
select {
case <-timer.C:
fmt.Println("timer fired")
}time.Tick и time.NewTicker
time.Tick удобен, но приводит к утечке внутреннего тикера — предпочитайте time.NewTicker, чтобы можно было вызвать Stop() и освободить ресурсы.
ticker := time.NewTicker(500 * time.Millisecond)
defer ticker.Stop()
for range ticker.C {
fmt.Println("tick")
}Тикер в цикле
Объедините тикер с каналом завершения, чтобы запускать периодическую работу и корректно останавливать её.
ticker := time.NewTicker(time.Second)
done := make(chan struct{})
go func() {
for {
select {
case <-ticker.C:
doWork()
case <-done:
ticker.Stop()
return
}
}
}()Утечка при использовании time.After
time.After создаёт новый таймер при каждом вызове, и таймер нельзя удалить сборщиком мусора, пока он не сработает. В тесном цикле используйте time.NewTimer и Reset, чтобы избежать утечки таймеров.
Крайний срок и тайм-аут
Тайм-аут — это относительный период («ждать 5 с»). Крайний срок — это абсолютный момент времени («ждать до 14:00»). Используйте time.Until(deadline), чтобы преобразовать крайний срок в период для time.After.
deadline := time.Now().Add(5 * time.Second)
select {
case v := <-ch:
use(v)
case <-time.After(time.Until(deadline)):
fmt.Println("deadline exceeded")
}context.WithTimeout предпочтителен
Для обработчиков HTTP и структурированной работы предпочитайте context.WithTimeout обычным тайм-аутам на каналах: этот механизм автоматически передаёт отмену по всему стеку вызовов.
ctx, cancel := context.WithTimeout(context.Background(), 2*time.Second)
defer cancel()Ограничение частоты с помощью тикера
Тикер — самый простой ограничитель частоты: отправляйте один запрос за каждый такт. Для поддержки всплесков заранее заполните буферизованный канал и пополняйте его с помощью тикера.
requests := make(chan int, 5)
for i := 0; i < 5; i++ { requests <- i }
close(requests)
limiter := time.NewTicker(200 * time.Millisecond)
for req := range requests {
<-limiter.C
fmt.Println("request", req)
}Монотонные часы
Длительности таймеров Go используют монотонные часы, а не системные, поэтому изменения системного времени на них не влияют. time.Since и time.Until также используют монотонные часы.
Правильная остановка тикера
После вызова ticker.Stop() канал тикера НЕ закрывается — он просто перестаёт получать значения. При необходимости перед возвратом извлеките из канала ожидающее значение.
Проверка знаний
Почему time.NewTicker предпочтительнее time.Tick?
Итоги: тайм-ауты и тикеры
Главное:
- time.After — для однократного тайм-аута в операторе select
- time.NewTicker — для повторяющейся работы; всегда вызывайте Stop()
- Избегайте time.After в циклах: это приводит к утечке таймеров
- Для работы с возможностью отмены предпочитайте context.WithTimeout
Часто задаваемые вопросы
Урок «Тайм-ауты и тикеры» бесплатный?
Да — полный текст урока «Тайм-ауты и тикеры» бесплатно доступен здесь в веб-версии. Чтобы практиковать его интерактивно (встроенный редактор кода и ИИ-репетитор 24/7) и разблокировать остальной курс Go Academy, подпишись на CoddyKit PRO. Курс Go Academy содержит 4 уроков всего.
Чему я научусь в уроке «Тайм-ауты и тикеры»?
Использование time.After и time.Tick с select Ты практикуешь Go Academy с помощью реального кода, который запускаешь прямо в браузере, и ИИ-репетитор 24/7 отвечает на твои вопросы во время урока.
Нужен ли мне опыт, чтобы начать Go Academy?
Предыдущий опыт не требуется. Go Academy на CoddyKit структурирован для всех уровней — от новичков до продвинутых, поэтому ты можешь начать отсюда или с самого начала и учиться в своем темпе. Это урок 2 из 4.
Сколько времени занимает урок «Тайм-ауты и тикеры»?
Большинство уроков CoddyKit занимают около 5–10 минут. Каждый из них компактный и интерактивный, поэтому ты постоянно делаешь прогресс и продолжаешь с того же места в веб-версии и приложении.
Можно ли писать и запускать код в этом уроке Go Academy?
Да. Каждый урок Go Academy включает встроенный редактор кода, поэтому ты пишешь и запускаешь реальный код прямо в браузере и получаешь моментальную обратную связь от AI — локальная установка не требуется.
Все уроки этого курса
- Оператор select
- Тайм-ауты и тикеры
- Шаблоны fan-in и fan-out
- Шаблон пула работников