Ce face time.After
time.After(d) creează un temporizator și îți dă canalul lui. După durata d, pe canal sosește momentul expirării. Locul lui obișnuit este într-un select, alături de canalul care aduce rezultatul: dacă rezultatul vine primul îl folosești, dacă vine întâi semnalul de la time.After, ai depășit timpul.
Din Go 1.23 temporizatorul este eliberat de colectorul de memorie chiar dacă nimeni nu citește canalul, deci time.After în bucle nu mai pierde memorie. Dacă vrei totuși să oprești temporizatorul devreme, folosește time.NewTimer și Stop. Pentru operații care trebuie anulate în lanț (cereri HTTP, interogări), preferă context.WithTimeout.
Parametri
| Parametru | Descriere |
|---|---|
d |
După cât timp sosește valoarea pe canal. |
Ce returnează
Un canal doar pentru citire (<-chan time.Time).
Exemple
Exemplul 1: Limită de timp pentru un calcul
Canalul rezultat are buffer 1, ca goroutine-ul să poată scrie și să se termine chiar dacă nimeni nu mai citește.
package main
import (
"fmt"
"time"
)
func cauta(produs string, durata time.Duration) <-chan string {
rezultat := make(chan string, 1)
go func() {
time.Sleep(durata) // simulăm o căutare lentă
rezultat <- produs + ": 3 bucăți în stoc"
}()
return rezultat
}
func main() {
select {
case r := <-cauta("laptop", 50*time.Millisecond):
fmt.Println("Găsit:", r)
case <-time.After(500 * time.Millisecond):
fmt.Println("Timpul a expirat")
}
select {
case r := <-cauta("frigider", 2*time.Second):
fmt.Println("Găsit:", r)
case <-time.After(100 * time.Millisecond):
fmt.Println("Căutarea pentru frigider a durat prea mult")
}
}
Rezultat
Găsit: laptop: 3 bucăți în stoc
Căutarea pentru frigider a durat prea mult
Exemplul 2: Valoarea primită
Pe canal sosește momentul expirării, care diferă la fiecare rulare.
package main
import (
"fmt"
"time"
)
func main() {
fmt.Println("Aștept 1 secundă...")
t := <-time.After(time.Second)
fmt.Println("Gata la", t.Format("15:04:05.000"))
}
Rezultat posibil (diferă la fiecare rulare)
Aștept 1 secundă...
Gata la 11:42:08.004
Greșeli frecvente
- Creezi canalul rezultatului fără buffer. Dacă expiră timpul, goroutine-ul rămâne blocat pentru totdeauna la scriere. Folosește
make(chan T, 1). - Pui
time.Afterîntr-unselectdin buclă crezând că limitează toată bucla: fiecare trecere creează un temporizator nou. Creează-l o dată, înainte de buclă.
Comenzi înrudite
time.Timer: Un temporizator care trimite un singur semnal pe canalul C după o durată; poate fi oprit (Stop) sau repornit (Reset).time.Tick: Returnează un canal care primește o valoare la fiecare interval d, la nesfârșit; bun pentru sarcini repetate.time.Sleep: Oprește goroutine-ul curent pentru durata dată (de exemplu 500*time.Millisecond), apoi continuă.context.WithTimeout: Creează un context care se anulează singur după durata dată; limita de timp standard pentru cereri și interogări.