如何在 Golang 中使用超时

go programmingserver side programmingprogramming

当我们不想等待某些 goroutine 的输出时,超时就发挥了重要作用,因为这些 goroutine 的执行时间超过了预期。需要注意的是,Go 语言本身并不支持超时,但我们可以很容易地实现它。

假设我们想从通道 ch 接收一些值,但我们不想等待超过 3 秒才能收到该值。如果我们在规定的 3 秒后才获得输出,那么我们希望丢弃它并打印另一条消息,而不是等待更长时间才能获得输出。

示例 1

我们首先探讨一个简单的案例,即在较长时间后获取函数的输出。

考虑下面的代码。

package main

import (
   "fmt"
   "time"
)

func timeConsuming() string {
   time.Sleep(5 * time.Second)
   return "The timeConsuming() function has stopped"
}

func main() {
   currentChannel := make(chan string, 1)

   go func() {
      text := timeConsuming()
      currentChannel <- text
   }()

   select {
   case res := <-currentChannel:
      fmt.Println(res)
   }
   fmt.Println("Main function exited!")
}

在上面的代码中,我们有一个名为 timeConsuming() 的函数,它表示函数可能在较长或期望的时间段后返回特定值的情况。例如,一个 Web 请求的数据获取时间过长,导致用户感到沮丧。

在上面代码的 ma​​in 函数中,我们有一个缓冲通道,然后借助 select 语句 等待数据到达。因此,在上面的例子中,整个代码必须等到 timeConsuming() 函数完成其工作。

输出

如果我们使用命令 go run main.go 运行上面的代码,我们将得到以下输出。

The timeConsuming() function has stopped
Main function exited!

示例 2

现在,假设我们不想等待 timeConsuming() 函数执行完成。在这种情况下,我们可以使用 time 包中的 After() 函数。

语法

After() 函数的语法如下:

func After(d Duration) −- chan Time

After 函数等待 d 持续时间执行完毕,然后在通道上返回当前时间。

请考虑下面的代码,其中我们使用 After 函数注册超时。

package main

import (
   "fmt"
   "time"
)

func timeConsuming() string {
   time.Sleep(5 * time.Second)
   return "The timeConsuming() function has stopped"
}

func main() {
   currentChannel := make(chan string, 1)

   go func() {
      text := timeConsuming()
      currentChannel <- text
   }()

   select {
   case res := <-currentChannel:
      fmt.Println(res)
   case <-time.After(3 * time.Second):
      fmt.Println("Out of time :(")
   }
   fmt.Println("Main function exited!")
}

输出

如果我们使用命令 go run main.go 运行上述代码,那么我们将得到以下输出。

Out of time :(
Main function exited!

相关文章