为什么我要在 golang 中使用 `case <-time.After(time.Second * 1):` 而不是 `time.Sleep(time.Second * 1)`
Why would I use `case <-time.After(time.Second * 1):` over `time.Sleep(time.Second * 1)` in golang
查看一些代码我发现了两种每秒做某事的方法:
for {
fmt.Println("This is printed every second")
time.Sleep(time.Second * 1)
}
和
for {
select {
case <-time.After(time.Second * 1):
fmt.Println("This is printed every second")
}
}
除了第一个更具可读性(在我看来)之外,我真的不明白一个比另一个有什么优势。有人知道吗?
您可能出于(至少)两个原因想要这样做:
time.Sleep
总是阻塞你当前的 goroutine,而如果你包含一个 default 情况,等待通道可能不会:
timeoutCh := time.After(time.Second)
LOOP:
for {
select {
case <-timeoutCh:
break LOOP
default:
}
// do some work
}
- 您可以使用它为长运行 操作添加超时。
假设您的 long-运行 op 将在频道上通知您。在那种情况下,该操作的超时将像这样实现:
opNotifyCh := op()
select {
case res := <-opNotifyCh:
fmt.Println("Op finished with result:", res)
case <-time.After(time.Second):
fmt.Println("Op timed out")
}
time.After
给你一个频道。你可以用它做任何你想做的事——你可以把它传递给一个函数,你可以 return 它给调用者,你可以把它放在一个结构中——任何东西,真的。这给了你很大的自由度。
查看一些代码我发现了两种每秒做某事的方法:
for {
fmt.Println("This is printed every second")
time.Sleep(time.Second * 1)
}
和
for {
select {
case <-time.After(time.Second * 1):
fmt.Println("This is printed every second")
}
}
除了第一个更具可读性(在我看来)之外,我真的不明白一个比另一个有什么优势。有人知道吗?
您可能出于(至少)两个原因想要这样做:
time.Sleep
总是阻塞你当前的 goroutine,而如果你包含一个 default 情况,等待通道可能不会:
timeoutCh := time.After(time.Second)
LOOP:
for {
select {
case <-timeoutCh:
break LOOP
default:
}
// do some work
}
- 您可以使用它为长运行 操作添加超时。
假设您的 long-运行 op 将在频道上通知您。在那种情况下,该操作的超时将像这样实现:
opNotifyCh := op()
select {
case res := <-opNotifyCh:
fmt.Println("Op finished with result:", res)
case <-time.After(time.Second):
fmt.Println("Op timed out")
}
time.After
给你一个频道。你可以用它做任何你想做的事——你可以把它传递给一个函数,你可以 return 它给调用者,你可以把它放在一个结构中——任何东西,真的。这给了你很大的自由度。