我有一个选择块,它正在收听 2 个频道、一个自动收报机和一个计时器:
package main
import (
"fmt"
"time"
)
func main() {
ticker := time.NewTicker(5 * time.Second)
for {
select {
case z := <-ticker.C:
fmt.Printf("tick %d\n", z)
case <-time.After(12 * time.Second):
fmt.Println("12 seconds elapsed!")
}
}
}
Run Code Online (Sandbox Code Playgroud)
如果我运行代码,time.After案例永远不会运行,但自动收报机工作正常。
如果我删除自动收报机,time.After则会正确触发:
package main
import (
"fmt"
"time"
)
func main() {
for {
select {
case <-time.After(12 * time.Second):
fmt.Println("12 seconds elapsed!")
}
}
}
Run Code Online (Sandbox Code Playgroud)
如果我使用计时器而不是time.After:
package main
import (
"fmt"
"time"
)
func main() {
ticker := time.NewTicker(5 * time.Second)
timer := time.NewTimer(12 * time.Second)
for {
select {
case z := <-ticker.C:
fmt.Printf("tick %d\n", z)
case <-timer.C:
fmt.Println("12 seconds elapsed!")
}
}
}
Run Code Online (Sandbox Code Playgroud)
为什么会发生这种情况?
Aselect阻塞直到它的一个 case 准备好,然后它执行那个 case。在您的示例中 time.After() 永远不会被调用。
func main() {
ticker := time.NewTicker(5 * time.Second)
for {
select {
case z := <-ticker.C:
fmt.Printf("tick %d\n", z)
//This never gets chance to be ready. It'll work if you make it less than 5 seconds.
case <-time.After(12 * time.Second):
fmt.Println("12 seconds elapsed!")
}
}
}
Run Code Online (Sandbox Code Playgroud)
您可以通过在for循环之前声明计时器来使其工作。
func main() {
ticker := time.NewTicker(5 * time.Second)
timer := time.After(12 * time.Second)
for {
select {
case z := <-ticker.C:
fmt.Printf("tick %d\n", z)
case <-timer:
fmt.Println("12 seconds elapsed!")
}
}
}
Run Code Online (Sandbox Code Playgroud)