【发布时间】:2016-08-20 14:21:22
【问题描述】:
我对 Go 比较陌生,并试图找出同时从 REST API 中提取信息的最佳方法。目的是对API 进行多次并发调用,每次调用都返回不同类型的数据。
我目前有:
s := NewClient()
c1 := make(chan map[string]Service)
c2 := make(chan map[string]ServicePlan)
c3 := make(chan map[string]ServiceInstance)
c4 := make(chan map[string]ServiceBinding)
c5 := make(chan map[string]Organization)
c6 := make(chan map[string]Space)
go func() {
c1 <- GetServices(s)
}()
go func() {
c2 <- GetServicePlans(s)
}()
go func() {
c3 <- GetServiceInstances(s)
}()
go func() {
c4 <- GetServiceBindings(s)
}()
go func() {
c5 <- GetOrganizations(s)
}()
go func() {
c6 <- GetSpaces(s)
}()
services := <- c1
servicePlans := <- c2
serviceInstances := <- c3
serviceBindings := <- c4
orgs := <- c5
spaces := <- c6
// stitch all the data together later
但我想知道是否有更好的方法来写这个。
编辑:它仍然很丑,但将频道数量减少到了一个:
c := make(chan interface{})
var (
services map[string]Service
servicePlans map[string]ServicePlan
serviceInstances map[string]ServiceInstance
serviceBindings map[string]ServiceBinding
orgs map[string]Organization
spaces map[string]Space
)
go func() {
c <- GetServices(s)
}()
go func() {
c <- GetServicePlans(s)
}()
go func() {
c <- GetServiceInstances(s)
}()
go func() {
c <- GetServiceBindings(s)
}()
go func() {
c <- GetOrganizations(s)
}()
go func() {
c <- GetSpaces(s)
}()
for i := 0; i < 6; i++ {
v := <-c
switch v := v.(type) {
case map[string]Service:
services = v
case map[string]ServicePlan:
servicePlans = v
case map[string]ServiceInstance:
serviceInstances = v
case map[string]ServiceBinding:
serviceBindings = v
case map[string]Organization:
orgs = v
case map[string]Space:
spaces = v
}
}
我仍然非常想要一种方法来执行此操作,因此我不必硬编码循环需要运行 6 次。我实际上尝试制作一个要运行的函数列表并以这种方式删除重复的go func 调用,但由于所有函数都有不同的返回类型,我得到了所有类型不匹配的错误,你不能通过使用来伪造它func(api) interface{} 那样只会造成运行时恐慌。
【问题讨论】:
-
您可能过度使用频道。如果请求已经并发并且每个都返回单一类型的结果,为什么还需要更多的 goroutine 和通道来接收结果?
-
这就是诀窍,每个返回不同类型的结果
-
您可以在闭包中分配值:play.golang.org/p/Sak5QGCPZi,或者您可以按照下面的建议进行操作并使用通用接口{}来接收任何类型。
-
关于那个的问题:我认为你必须使用通道而不是在 goroutine 内部进行直接分配。这不是真的吗?
-
不,将闭包作为 goroutine 调度是非常惯用的。您始终必须确保永远不会有并发读取和写入,但是 WaitGroup 提供了同步。