如何在Go語言中使用超時


當我們不想等待某些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()的函式,它表示一個可能在較長時間或所需時間後返回特定值的函式。一個例子是網路請求,其中獲取資料花費的時間太長,使用者感到沮喪。

在上面程式碼的main函式中,我們有一個帶緩衝區的通道,然後我們使用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!

更新於:2021年11月1日

3K+ 次瀏覽

啟動你的職業生涯

透過完成課程獲得認證

開始學習
廣告