0Pricing
Go Academy · Урок

Тайм-ауты и тикеры

Использование 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 — локальная установка не требуется.

Все уроки этого курса

  1. Оператор select
  2. Тайм-ауты и тикеры
  3. Шаблоны fan-in и fan-out
  4. Шаблон пула работников
← Назад к Go Academy