发布时间:2024-12-23 00:14:24
Golang有一个强大的标准库,提供了方便的工具来处理HTTP请求。它采用了并发模型(Goroutines)和并发安全的数据结构(如Channels)来帮助我们实现高效和可扩展的多个HTTP请求。
要使用goroutine进行并发,我们可以使用Go关键字在每个请求中启动一个goroutine。在以下示例中,我们发起了两个HTTP GET请求并同时处理它们的结果:
``` package main import ( "fmt" "io/ioutil" "net/http" ) func main() { urls := []string{"https://api.example.com/users/1", "https://api.example.com/users/2"} for _, url := range urls { go func(u string) { resp, err := http.Get(u) if err != nil { fmt.Printf("Error fetching %s: %s\n", u, err.Error()) return } defer resp.Body.Close() body, err := ioutil.ReadAll(resp.Body) if err != nil { fmt.Printf("Error reading response body: %s\n", err.Error()) return } fmt.Printf("Response from %s: %s\n", u, body) }(url) } // 等待所有goroutine完成 select {} } ``` 在上述示例中,我们使用一个循环来遍历URL列表,并使用`go`关键字在每个迭代中启动一个goroutine。每个goroutine都执行指定的函数,发起一个HTTP GET请求,并处理返回的结果。 我们使用`http.Get()`函数发送请求并获取响应。然后,我们使用`ioutil.ReadAll()`函数读取响应的内容。最后,我们打印出每个请求的响应体。下面的示例代码展示了如何使用Channels来收集多个请求的结果:
``` package main import ( "fmt" "io/ioutil" "net/http" ) func main() { urls := []string{"https://api.example.com/users/1", "https://api.example.com/users/2"} responses := make(chan []byte) for _, url := range urls { go func(u string) { resp, err := http.Get(u) if err != nil { fmt.Printf("Error fetching %s: %s\n", u, err.Error()) return } defer resp.Body.Close() body, err := ioutil.ReadAll(resp.Body) if err != nil { fmt.Printf("Error reading response body: %s\n", err.Error()) return } responses <- body }(url) } // 等待所有goroutine完成并关闭通道 go func() { for range urls { <-responses } close(responses) }() for response := range responses { fmt.Printf("Response: %s\n", response) } } ``` 在上面的示例中,我们创建了一个`responses`通道,用于接收每个请求的响应。 在每个goroutine中,我们将响应的内容发送到`responses`通道中。然后,在主线程中,我们使用`range`循环从`responses`通道中读取每个响应,并对其进行处理。请注意,在循环之前,我们使用另一个goroutine来等待所有的goroutines完成并关闭通道。这是为了确保主线程不会在还有goroutines在运行时终止循环。
参考链接:
- Golang官方文档:https://golang.org/doc/ - Go by Example:https://gobyexample.com/ - HTTP请求处理:https://golang.org/pkg/net/http/