介绍
这篇文章给大家介绍未来和承诺怎么在Golang中使用,内容非常详细,感兴趣的小伙伴们可以参考借鉴,希望对大家能有所帮助。
一个未来就是说“将来“你需要某些东西(一般就是一个网络请求的结果),但是你现在就要发起这样的请求,并且这个请求会异步执行。或者换一个说法,你需要在后台执行一个异步请求。
未来/承诺模式在多种语言都有对应的实现。比如ES2015就有承诺和async-await, Scala内置了未来,最后在Golang里有goroutine和通道可以实现类似的功能。下面给出一个简单的实现。
//RequestFuture http request 承诺。 func RequestFuture (url 字符串),& lt; -chan [] byte { ,,,c :=, (chan []字节,1) ,,,go func (), { ,,,,,,,var body []字节 ,,,,,,,defer func (), { ,,,,,,,,,,,c & lt;作用;身体 ,,,,,,,}() ,,,,,,,,,err :=, http.Get (url) ,,,,,,,if err !=, nil { ,,,,,,,,,,,回来 ,,,,,,,} ,,,,,,,defer res.Body.Close () ,,,,,,,,,_ =, ioutil.ReadAll (res.Body) ,,,}() ,,return c } func main (), { future 才能;:=,RequestFuture (“https://api.github.com/users/octocat/orgs") body 才能:=& lt;未来 log.Printf才能(时间长度:“reponse % d",, len(身体)) }
<代码> RequestFuture 代码>方法理科返回一个频道,这个时候http请求还在一个goroutine后台异步运行.main方法可以继续执行其他的代码,比如触发其他的<代码> 代码>等。当需要结果的时候,我们需要从通道里读取结果。如果http请求还没有返回的话就会阻塞当前的goroutine,知道结果返回。
然而,以上的方法还有一点局限。错误无法返回。在上面的例子里,如果http请求出现错误的话,身体的值会是零/空的。但是,由于通道只能返回一个值,你需要创建一个单独的结构来包装两个返回的结果。
修改以后的结果:
//,RequestFutureV2 return value 以及错误 func RequestFutureV2 (url 字符串),func(),([]字节,,错误),{ ,,,var body []字节 ,,,var err 错误 ,,,c :=, (chan 结构{},,1) ,,,go func (), { ,,,,,,,defer 密切(c) ,,,,,,,var res * http.Response ,,,,,,,,,err =, http.Get (url) ,,,,,,,if err !=, nil { ,,,,,,,,,,,回来 ,,,,,,,} ,,,,,,,defer res.Body.Close () ,,,,,,,,,err =, ioutil.ReadAll (res.Body) ,,,}() ,,,return func(),([]字节,,错误),{ ,,,,,,,& lt; - c ,,,,,,,return 身体,犯错 ,,,} }
这个方法返回了两个结果,解决了第一个方法的局限性问题。使用的时候是这样的:
func 主要(),{ ,,,futureV2 :=, RequestFutureV2 (“https://api.github.com/users/octocat/orgs") ,,,//not 阻止 ,,,log.Printf (“V2  is 却;能够locked again") ,,,,err bodyV2:=, futureV2(),//块 ,,,if err ==, nil { ,,,,,,,log.Printf (“V2  response length % d \ n",, len (bodyV2)) ,,,},{else ,,,,,,,log.Printf (“V2  error is % v \ n",,呃) ,,,} }
上面的修改带来的好处就是<代码> futureV2() 代码>方法的调用可以是多次的。并且都可以返回同样的结果。
但是,如果你想用这个方法实现很多不同的异步功能,你需要写很多的额外的代码。我们可以写一个跑龙套方法来克服这个困难。
//,Future boilerplate 方法 func 未来(f func(),(接口{},,错误),func(),(接口{},,错误),{ ,,,var result 界面{} ,,,var err 错误 ,,,c :=, (chan 结构{},,1) ,,,go func (), { ,,,,,,,defer 密切(c) ,,,,,,,,,err =, f () ,,,}() ,,,return func(),(接口{},,错误),{ ,,,,,,,& lt; - c null null null未来和承诺怎么在Golang中使用