现如今,应用执行时最普遍存在的瓶颈就是网络请求了。网络请求只要几毫秒,但是等到返回却要百倍的时间。所以,如果你执行多个网络请求,让他们都并行执行就是减少延迟最好的选择了。Future/Promise就是实现这一目的的手段之一。

一个Future就是说“将来”你需要某些东西(一般就是一个网络请求的结果),但是你现在就要发起这样的请求,并且这个请求会异步执行。或者换一个说法,你需要在后台执行一个异步请求。

Future/Promise模式在多种语言都有对应的实现。比如ES2015就有Promise和async-await,Scala内置了Future,最后在Golang里有goroutine和channel可以实现类似的功能。下面给出一个简单的实现。

//RequestFuture, http request promise.
func RequestFuture(url string) <-chan []byte {c := make(chan []byte, 1)go func() {var body []bytedefer func() {c <- body}()res, err := http.Get(url)if err != nil {return}defer res.Body.Close()body, _ = ioutil.ReadAll(res.Body)}()return c
}func main() {future := RequestFuture("https://api.github.com/users/octocat/orgs")body := <-futurelog.Printf("reponse length: %d", len(body))
}

RequestFuture方法理科返回一个channel,这个时候http请求还在一个goroutine后台异步运行。main方法可以继续执行其他的代码,比如触发其他的Future等。当需要结果的时候,我们需要从channel里读取结果。如果http请求还没有返回的话就会阻塞当前的goroutine,知道结果返回。

然而,以上的方法还有一点局限。错误无法返回。在上面的例子里,如果http请求出现错误的话,body的值会是nil/empty。但是,由于channel只能返回一个值,你需要创建一个单独的struct来包装两个返回的结果。

修改以后的结果:

// RequestFutureV2 return value and error
func RequestFutureV2(url string) func() ([]byte, error) {var body []bytevar err errorc := make(chan struct{}, 1)go func() {defer close(c)var res *http.Responseres, err = http.Get(url)if err != nil {return}defer res.Body.Close()body, err = ioutil.ReadAll(res.Body)}()return func() ([]byte, error) {<-creturn body, err}
}

这个方法返回了两个结果,解决了第一个方法的局限性问题。使用的时候是这样的:

func main() {futureV2 := RequestFutureV2("https://api.github.com/users/octocat/orgs")// not blocklog.Printf("V2 is this locked again")bodyV2, err := futureV2() // blockif err == nil {log.Printf("V2 response length %d\n", len(bodyV2))} else {log.Printf("V2 error is %v\n", err)}
}

上面的修改带来的好处就是futureV2()方法的调用可以是多次的。并且都可以返回同样的结果。

但是,如果你想用这个方法实现很多不同的异步功能,你需要写很多的额外的代码。我们可以写一个util方法来克服这个困难。

// Future boilerplate method
func Future(f func() (interface{}, error)) func() (interface{}, error) {var result interface{}var err errorc := make(chan struct{}, 1)go func() {defer close(c)result, err = f()}()return func() (interface{}, error) {<-creturn result, err}
}

调用Future方法的时候会执行房里的很多channel方面的小技巧。为了能够达到通用的目的有一个从[]buyte->interface{}->[]byte的类型转换。如果出现错的话会引发一个运行时的panic

原文: http://labs.strava.com/blog/f...

Stay tuned to my next episode

Golang里的Future/Promise相关推荐

  1. future promise java_Future与Promise

    https://code.csdn.NET/DOC_Scala/chinese_scala_offical_document/file/Futures-and-Promises-cn.md#ancho ...

  2. C++异步调用利器future/promise实现原理

    前言 在异步编程中,各种回调将让人眼花缭乱,代码分散,维护起来十分困难.boost和C++11 的 future/promise 提供了一个很好的解决方案,使得代码更加漂亮.易维护. 在工作中,我也用 ...

  3. rust异步编程--理解并发/多线程/回调/异步/future/promise/async/await/tokio

    1. 异步编程简介 通常我们将消息通信分成同步和异步两种: 同步就是消息的发送方要等待消息返回才能继续处理其它事情 异步就是消息的发送方不需要等待消息返回就可以处理其它事情 很显然异步允许我们同时做更 ...

  4. folly教程系列之:future/promise

         attension:本文严禁转载. 一.前言 promise/future是一个非常重要的异步编程模型,它可以让我们摆脱传统的回调陷阱,从而使用更加优雅.清晰的方式进行异步编程.c++11中 ...

  5. 【转】现代c++开发利器folly教程系列之:future/promise

    一.前言 promise/future是一个非常重要的异步编程模型,它可以让我们摆脱传统的回调陷阱,从而使用更加优雅.清晰的方式进行异步编程.c++11中已经开始支持std::future/std:: ...

  6. future promise java_第四章 Future和Promise

    Netty是一个异步网络处理框架,在实现中大量使用了Future机制,并在Java自带Future的基础上,增加了Promise机制.这两者的目的都是使异步编程更加方便使用.在阅读源码之前,我们需要对 ...

  7. future promise shared_future简单使用

    #include #include #include /furture 和promi******************/ int display(const int& value) { re ...

  8. c++11 future promise

    std::future std::future 代表未来得到,可以使用std::async 来执行 std::async 为异步编程的高级封装,封装了std::future的操作,基本上可以代替std ...

  9. 在Golang里如何实现结构体成员指针到结构体自身指针的转换

    原文地址:http://goworldgs.com/?p=37 在C语言中有一个经典的宏定义,可以将结构体struct内部的某个成员的指针转化为结构体自身的指针.下面是一个例子,通过FIELD_OFF ...

  10. lru算法C语言结构体指针,在Golang里如何实现结构体成员指针到结构体自身指针的转换...

    在C语言中有一个经典的宏定义,可以将结构体struct内部的某个成员的指针转化为结构体自身的指针.下面是一个例子,通过FIELD_OFFSET宏计算结构体内一个字段的偏移,函数getT可以从一个F*的 ...

最新文章

  1. 甲方乙方和站在外包中间的你 | 每日趣闻
  2. 前紫光展锐CTO创业造芯:主打边缘AI视觉,融资10亿,9个月流片
  3. 基于sklearn的朴素贝叶斯_Sklearn参数详解—贝叶斯
  4. 一起学习C语言:结构体(一)
  5. c语言sizeof(test),解析C语言中的sizeof
  6. android系统(107)---Android路由表设置(route amp; DNS)
  7. excell之如何添加下拉菜单,测试用例配置优先级
  8. python元类_Python中元类
  9. awk命令详解+示例
  10. word整个表格首行缩进_word表格怎么首行缩进 word表格内容缩进
  11. 关于广告投放系统:广告竞拍(2018)
  12. 从团队协作的五大障碍看团队管理该怎么做
  13. 摩拜+小程序,让单车变得“触手可骑”
  14. 【拜占庭将军问题】这一计谋,可以让诸葛丞相兴复汉室
  15. Intel汇编-LOOP循环检查ECX含零值
  16. 滴滴出行2016校招编程题
  17. 高校宿舍管理系统详细需求分析说明书
  18. 第8周训练总结(4.20)
  19. 洋码头API接口:item_search - 根据关键词取商品列表
  20. 发现(1)之如何申请CSDN博客专栏

热门文章

  1. Atitit 快速开发体系建设路线图
  2. Atitit 项目源码的架构,框架,配置与环境说明模板 规范 标准化
  3. Atitit.dart语言的特性  编译时js语言大总结
  4. atitit.系统托盘图标的设计java swing c# .net c++ js
  5. 英方软件:以“数据复制”为起点来赋能行业
  6. Rust : actor模式 与 Actix库
  7. (转)鼎晖投资总裁焦震:别把投资高雅化,就是个做买卖的
  8. (转)机会还是陷阱:诺亚财富的私募股权策略
  9. Atom: 安装版本过旧,会导致很多问题
  10. 技术人 | 我在支付宝体验技术部这四年学到了什么?