我有以下函数用于获取URL并将数据返回到接口(例如struct / int / whatever):
var httpClient = &http.Client{Timeout: 10 * time.Second}
func getURLToTarget(url string, target interface{}) error {
req, err := httpClient.Get(url)
if err != nil {
return err
}
defer req.Body.Close()
return json.NewDecoder(req.Body).Decode(target)
}
然后我有几个看起来像这样的函数:
func GetCustomerByID(APIKey, cusID string) {
cus := new(Customer)
getURLToTarget(fmt.Sprintf("http://someurl.com/%s/customerbyid/:%s", APIKey, cusID), &cus)
}
在这种情况下会将json响应保存到这样的结构中:
type Customer struct {
Name string
Email string
Address string
}
现在我的问题是,当我运行时,如何让所有这些http请求同时执行:
func main() {
apikey := "some api key"
GetCustomerByID(apikey, "43279843")
GetCustomerDiscounts(apikey, "43279843")
GetProductByID(apikey, "32124")
}
我很确定我需要使用频道,但我无法弄清楚如何...任何帮助都会非常感激
答案 0 :(得分:1)
有很多方法可以达到这个目的,并且它取决于你需要发生什么。
基本的一个是使用goroutines和wg.WaitGroup并行/并发执行http调用,并在退出程序之前等待所有这些调用完成。例如:
func main() {
apikey := "some api key"
var wg sync.WaitGroup
wg.Add(3)
go func() {
GetCustomerByID(apikey, "43279843")
wg.Done()
}()
go func() {
GetCustomerDiscounts(apikey, "43279843")
wg.Done()
}()
go func() {
GetProductByID(apikey, "32124")
wg.Done()
}()
wg.Wait()
}
另一种方法是,如果要检查每个http调用的结果,请使用go通道。例如:
func GetCustomerByID(APIKey, cusID string) Customer {
cus := new(Customer)
getURLToTarget(fmt.Sprintf("http://someurl.com/%s/customerbyid/:%s", APIKey, cusID), &cus)
return cus
}
func main() {
apikey := "some api key"
c := make(chan Customer, 3)
go func() {
cus := GetCustomerByID(apikey, "43279843")
c <- cus
}()
go func() {
cus := GetCustomerDiscounts(apikey, "43279843")
c <- cus
}()
go func() {
cus := GetProductByID(apikey, "32124")
c <- cus
}()
// Print the result
var i int
for cus := range c {
fmt.Printf("%#v\n", cus)
i++
if i == 3 {
break
}
}
}