未来和承诺怎么在Golang中使用

  介绍

这篇文章给大家介绍未来和承诺怎么在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中使用