|
Допустим, мы выполняем внешний вызов, который
возвращает результат в канал c1 через 2 секунды.
Обрати внимание, что канал буферизованный, поэтому
отправка в горутине неблокирующая. Это распространённый
паттерн для предотвращения утечки горутин в случае,
если из канала никогда не прочитают.
|
c1 := make(chan string, 1)
go func() {
time.Sleep(2 * time.Second)
c1 <- "result 1"
}()
|
|
Вот select, реализующий таймаут.
res := <-c1 ожидает результат, а <-time.After
ожидает значение, которое будет отправлено после
таймаута в 1 секунду. Поскольку select выполняет
первое готовое получение, мы попадём в случай таймаута,
если операция займёт больше разрешённой 1 секунды.
|
select {
case res := <-c1:
fmt.Println(res)
case <-time.After(1 * time.Second):
fmt.Println("timeout 1")
}
|
|
Если мы установим более длинный таймаут в 3 секунды,
то получение из c2 успеет выполниться и мы выведем результат.
|
c2 := make(chan string, 1)
go func() {
time.Sleep(2 * time.Second)
c2 <- "result 2"
}()
select {
case res := <-c2:
fmt.Println(res)
case <-time.After(3 * time.Second):
fmt.Println("timeout 2")
}
}
|