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.")
}
解释
-
WaitGroup:使用
sync.WaitGroup来等待所有 goroutine 完成。 -
fetchURL 函数:每个请求由
fetchURL函数处理,该函数启动一个 HTTP GET 请求并输出响应状态码。 -
启动 goroutine:在
main函数中,为每个 URL 启动一个 goroutine。 -
等待完成:
wg.Wait()阻塞主 goroutine,直到所有请求处理完毕。
这种方式可以有效地利用 Go 的并发特性,提高程序的响应速度和效率。
defer resp.Body.Close() 可以放在上面吗?
在调用 http.Get(url) 后,应该检查错误并确保响应不为 nil,然后再使用 defer resp.Body.Close()。如果将 defer 放在错误检查之前,可能会导致程序在 resp 为 nil 时尝试关闭 Body,从而引发运行时错误。
正确的顺序应该是:
resp, err := http.Get(url)
if err != nil {
fmt.Println("Error:", err)
return
}
defer resp.Body.Close()
// 处理响应
这样可以确保只有在成功获取响应后才会调用 Close()。