【问题标题】:What is the idiomatic way of dealing with return data from a conditionally asynchronous function?处理来自条件异步函数的返回数据的惯用方式是什么?
【发布时间】:2018-09-11 05:24:32
【问题描述】:

我有一个函数,它可能会或可能不会被称为异步 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 调用,即传入一个通道;我们构建请求并将响应写入所提供通道的 *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 并留给调用者执行来自 goroutine 的调用。
  • 如何解决是否需要通道的歧义?
  • 同步 API 不使用通道。惯用的方法是从HTTPRequest 中删除responeChan,然后简单地从函数中返回&amp;twitterHTTPResponse{body, nil}, err

标签: asynchronous go goroutine


【解决方案1】:

惯用的方法是提供同步 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} 
}

如果需要同时运行调用,调用者 an 可以轻松创建一个 goroutine。例如:

r := make(chan *HTTPResponse) 
go func() {
    r <- APICall(req)
}()

... do some other work

resp := <- r

由于以下几个原因,同步 API 是惯用的:

  • 同步 API 更易于使用和理解。
  • 同步 API 不会对应用程序如何管理并发性做出错误假设。例如,应用程序可能希望使用等待组来等待完成,而不是像 API 假设的那样在通道上接收。

【讨论】:

  • 谢谢瑟瑞丝。这是否主要是因为 API 请求通常涉及使用本身已经高度异步的 net/http 标准库? (因此,如果 API 函数与其他应用程序逻辑正确分离,理论上将其作为 goroutine 运行应该几乎没有好处?)
  • 我更新了答案以描述为什么同步 API 是惯用的。 net/http 客户端 API 是同步的。
猜你喜欢
  • 2018-08-23
  • 2022-01-21
  • 2018-10-25
  • 2015-08-27
  • 1970-01-01
  • 2022-06-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多