处理来自条件异步函数的 return 数据的惯用方法是什么?
What is the idiomatic way of dealing with return data from a conditionally asynchronous function?
我有一个函数可以调用也可以不调用为异步 go-routine。
func APICall(request *HTTPRequest) *HTTPResponse
*HTTPRequest
是指向结构的指针,该结构包含构建请求所需的各种数据:
type HTTPRequest struct {
// Represents a request to the twitter API
method string
baseurl string
urlParams map[string]string
bodyParams map[string]string
authParams map[string]string
responseChan chan *HTTPResponse
}
如果作为goroutine调用,即传入一个channel;我们构建请求并将响应写入所提供通道的 *HTTPResponse 对象(也是一个结构)。在没有通道的情况下接受函数调用的最优雅/惯用的方式是什么(即非异步)
目前,我们在 APICall 的主体中做这样的事情来处理两种函数调用:
if request.responseChan != nil { // If a response channel has been specified, write to that channel
request.responseChan <- &twitterHTTPResponse{body, nil}
return nil // Not returning a struct
} else {
return &twitterHTTPResponse{body, nil} // Return a pointer to a new struct representing the response
}
我们走对路了吗?
惯用的方法是提供同步 API:
type HTTPRequest struct {
// Represents a request to the twitter API
method string
baseurl string
urlParams map[string]string
bodyParams map[string]string
authParams map[string]string
}
func APICall(request *HTTPRequest) *HTTPResponse {
...
return &twitterHTTPResponse{body, nil}
}
如果调用者需要并发 运行 调用,则可以轻松创建 goroutine。例如:
r := make(chan *HTTPResponse)
go func() {
r <- APICall(req)
}()
... do some other work
resp := <- r
同步 API 是惯用的,原因如下:
- 同步 API 更易于使用和理解。
- 同步 APIs 不会对应用程序如何管理并发做出错误的假设。例如,应用程序可能希望使用等待组来等待完成,而不是像 API.
假设的那样在通道上接收。
我有一个函数可以调用也可以不调用为异步 go-routine。
func APICall(request *HTTPRequest) *HTTPResponse
*HTTPRequest
是指向结构的指针,该结构包含构建请求所需的各种数据:
type HTTPRequest struct {
// Represents a request to the twitter API
method string
baseurl string
urlParams map[string]string
bodyParams map[string]string
authParams map[string]string
responseChan chan *HTTPResponse
}
如果作为goroutine调用,即传入一个channel;我们构建请求并将响应写入所提供通道的 *HTTPResponse 对象(也是一个结构)。在没有通道的情况下接受函数调用的最优雅/惯用的方式是什么(即非异步)
目前,我们在 APICall 的主体中做这样的事情来处理两种函数调用:
if request.responseChan != nil { // If a response channel has been specified, write to that channel
request.responseChan <- &twitterHTTPResponse{body, nil}
return nil // Not returning a struct
} else {
return &twitterHTTPResponse{body, nil} // Return a pointer to a new struct representing the response
}
我们走对路了吗?
惯用的方法是提供同步 API:
type HTTPRequest struct {
// Represents a request to the twitter API
method string
baseurl string
urlParams map[string]string
bodyParams map[string]string
authParams map[string]string
}
func APICall(request *HTTPRequest) *HTTPResponse {
...
return &twitterHTTPResponse{body, nil}
}
如果调用者需要并发 运行 调用,则可以轻松创建 goroutine。例如:
r := make(chan *HTTPResponse)
go func() {
r <- APICall(req)
}()
... do some other work
resp := <- r
同步 API 是惯用的,原因如下:
- 同步 API 更易于使用和理解。
- 同步 APIs 不会对应用程序如何管理并发做出错误的假设。例如,应用程序可能希望使用等待组来等待完成,而不是像 API. 假设的那样在通道上接收。