Skip to main content

go routine fetch

是的,Go 中的 goroutine 非常适合处理并发请求。你可以为每个请求启动一个 goroutine,以便同时处理多个请求。以下是一个简单的示例,展示如何使用 goroutine 处理并发请求:

package main

import (
"fmt"
"net/http"
"sync"
)

func fetchURL(wg *sync.WaitGroup, url string) {
defer wg.Done()
resp, err := http.Get(url)
if err != nil {
fmt.Println("Error:", err)
return
}
defer resp.Body.Close()
fmt.Println("Fetched:", url, "Status Code:", resp.StatusCode)
}

func main() {
var wg sync.WaitGroup
urls := []string{
"http://example.com",
"http://example.org",
"http://example.net",
}

for _, url := range urls {
wg.Add(1)
go fetchURL(&wg, url)
}

wg.Wait()
fmt.Println("All requests completed.")
}

解释

  1. WaitGroup:使用 sync.WaitGroup 来等待所有 goroutine 完成。

  2. fetchURL 函数:每个请求由 fetchURL 函数处理,该函数启动一个 HTTP GET 请求并输出响应状态码。

  3. 启动 goroutine:在 main 函数中,为每个 URL 启动一个 goroutine。

  4. 等待完成wg.Wait() 阻塞主 goroutine,直到所有请求处理完毕。

这种方式可以有效地利用 Go 的并发特性,提高程序的响应速度和效率。

defer resp.Body.Close() 可以放在上面吗?

在调用 http.Get(url) 后,应该检查错误并确保响应不为 nil,然后再使用 defer resp.Body.Close()。如果将 defer 放在错误检查之前,可能会导致程序在 respnil 时尝试关闭 Body,从而引发运行时错误。

正确的顺序应该是:

resp, err := http.Get(url)
if err != nil {
fmt.Println("Error:", err)
return
}
defer resp.Body.Close()
// 处理响应

这样可以确保只有在成功获取响应后才会调用 Close()