发布时间:2024-11-05 19:38:31
Go语言是一门以并发为核心的编程语言,通过goroutine和channel等原生支持的功能,可以轻松地实现高效的并发编程。本文将介绍如何使用Golang来实现并发调用API,并演示并发调用且无阻塞的访问多个API的示例。
Golang中的goroutine是一种非常轻量级的线程,它能够实现高并发和可扩展性。我们可以使用goroutine来实现并发调用API。下面是一个简单的示例,展示了如何并发调用多个API并将结果汇总:
package main
import (
"fmt"
"net/http"
"sync"
)
func fetchAPI(url string, wg *sync.WaitGroup, result chan<- string) {
defer wg.Done()
resp, err := http.Get(url)
if err != nil {
result <- fmt.Sprintf("Error fetching %s: %s", url, err.Error())
return
}
result <- fmt.Sprintf("API %s returned status code %d", url, resp.StatusCode)
}
func main() {
urls := []string{"https://api.example.com/1", "https://api.example.com/2", "https://api.example.com/3"}
var wg sync.WaitGroup
result := make(chan string)
for _, url := range urls {
wg.Add(1)
go fetchAPI(url, &wg, result)
}
go func() {
wg.Wait()
close(result)
}()
for res := range result {
fmt.Println(res)
}
}
Golang的channel是一种用于在goroutine之间进行通信的机制。在并发调用API的过程中,我们可以使用channel来汇总每个API的结果。下面是一个使用channel进行结果汇总的简单示例:
package main
import (
"fmt"
"net/http"
)
type APIResult struct {
API string
Status int
Message string
}
func fetchAPI(url string, result chan<- APIResult) {
resp, err := http.Get(url)
if err != nil {
result <- APIResult{API: url, Message: fmt.Sprintf("Error fetching %s: %s", url, err.Error())}
return
}
result <- APIResult{API: url, Status: resp.StatusCode}
}
func main() {
urls := []string{"https://api.example.com/1", "https://api.example.com/2", "https://api.example.com/3"}
result := make(chan APIResult)
for _, url := range urls {
go fetchAPI(url, result)
}
for range urls {
res := <-result
fmt.Printf("API %s returned status code %d\n", res.API, res.Status)
}
}
有时候,我们希望等待所有API的调用都完成后再继续进行其他操作。可以通过Golang的sync.WaitGroup来实现这一目标。下面是一个示例代码,演示了如何使用sync.WaitGroup等待所有API的调用完成:
package main
import (
"fmt"
"net/http"
"sync"
)
func fetchAPI(url string, wg *sync.WaitGroup, result chan<- string) {
defer wg.Done()
resp, err := http.Get(url)
if err != nil {
result <- fmt.Sprintf("Error fetching %s: %s", url, err.Error())
return
}
result <- fmt.Sprintf("API %s returned status code %d", url, resp.StatusCode)
}
func main() {
urls := []string{"https://api.example.com/1", "https://api.example.com/2", "https://api.example.com/3"}
var wg sync.WaitGroup
result := make(chan string)
for _, url := range urls {
wg.Add(1)
go fetchAPI(url, &wg, result)
}
go func() {
wg.Wait()
close(result)
}()
for res := range result {
fmt.Println(res)
}
}