最近在https://github.com/ThoughtWorksInc/rest-rpc上工作,遇到了一个scala隐式转换的问题,简单的说是要实现这么个东西:

implicit def jsonStreamFutureToScalaFuture[Value](jsonStreamFuture: IFuture1[Value]):Future[Value] = ???

把一种类型的Future(com.qifun.jsonStream.rpc.IFuture1)转换成为另一种类型的Future(scala.concurrent.Future)。

其中第一种Future的定义如下:

public interface IFuture1<AwaitResult> {
void start(ICompleteHandler1<AwaitResult> var1);
}

而ICompleteHandler1的定义为:

public interface ICompleteHandler1<AwaitResult> {
void onSuccess(AwaitResult var1); void onFailure(Object var1);
}

彼时对Future和Promise的概念还没有太好的理解,所以把一个未来变换成为另一个未来这种虚无缥缈的东西还是有点想象不来。于是尝试手工实现,

第一版的想法是触发jsonStreamFuture的start方法,传给它一个ICompleteHandler1的实现,然后等到onSuccess方法得到调用的时候,把var1这个结果保存到jsonStreamFutureToScalaFuture这个函数的局部变量中(给其命名为acceptVar吧)。然后再定义一个Future,在Future的实现中不断的检查acceptVar是否有值了,如果有了则返回。这种朴素的想法写出来就是这样:

implicit def jsonStreamFutureToScalaFuture[Value](jsonStreamFuture: IFuture1[Value]):Future[Value] = {
var acceptVar:Any = None jsonStreamFuture.start(new ICompleteHandler1[Value] {
override def onSuccess(value: Value): Unit = acceptVar = value
override def onFailure(ex: scala.Any): Unit = ???
}) new Future {
def onSuccess[U](pf: PartialFunction[Value, Unit]): Unit = {
while (acceptVar == None) {
}
pf(acceptVar.asInstanceOf[Value])
}
}
}

当然这是编译不过的。。。

但即使能够编过,这种while循环的方式也是丑陋的无法接受的。所以开始探索更好的方式,既然在ICompleteHandler1的onSuccss函数中能够得到value,那主动去触发将要返回的那个Future实例内保存的onSuccess的回调如何?想让强类型的语言编译通过比较费劲,所以下面的代码还只是用来demo想法的:

implicit def jsonStreamFutureToScalaFuture[Value](jsonStreamFuture: IFuture1[Value]):Future[Value] = {
var future = new Future(
var successCallBack;
def onSuccess(success: Success): Unit = {
this.successCallBack = success;
}
) jsonStreamFuture.start(new ICompleteHandler1[Value] {
override def onSuccess(value: Value): Unit = future.successCallBack(value)
override def onFailure(ex: scala.Any): Unit = ???
})
future
}

所以当我最后使用Promise来解决类似问题的示例代码时候,我就意识到其思想和上述的第二种方法是类似的,写出来是这样的:

implicit def jsonStreamFutureToScalaFuture[Value](jsonStreamFuture: IFuture1[Value]):Future[Value] = {
val p = Promise[Value]() jsonStreamFuture.start(new ICompleteHandler1[Value] {
override def onSuccess(value: Value): Unit = p success value
override def onFailure(ex: scala.Any): Unit = p failure ex.asInstanceOf[Throwable]
}) p.future
}

好吧,其实本文并没有自己实现一个Promise,不过通过这种重新构造现有概念的方式(当然也是因为自己的无知- -)确实能够帮助对现有概念的理解。

一步步实现Promise的更多相关文章

  1. 8张图让你一步步看清 async/await 和 promise 的执行顺序

    摘要: 面试必问 原文:8张图帮你一步步看清 async/await 和 promise 的执行顺序 作者:ziwei3749 Fundebug经授权转载,版权归原作者所有. 为什么写这篇文章? 说实 ...

  2. 8 张图帮你一步步看清 async/await 和 promise 的执行顺序(转)

    https://mp.weixin.qq.com/s?__biz=MzAxODE2MjM1MA==&mid=2651555491&idx=1&sn=73779f84c289d9 ...

  3. JQ中的延迟对象deferred中的promise等的使用

    一.什么是deferred对象? 开发网站的过程中,我们经常遇到某些耗时很长的javascript操作.其中,既有异步的操作(比如ajax读取服务器数据),也有同步的操作(比如遍历一个大型数组),它们 ...

  4. 【javascript】异步编年史,从“纯回调”到Promise

    异步和分块——程序的分块执行   一开始学习javascript的时候, 我对异步的概念一脸懵逼, 因为当时百度了很多文章,但很多各种文章不负责任的把笼统的描述混杂在一起,让我对这个 JS中的重要概念 ...

  5. 实现简单的promise

    只考虑成功时的调用,方便理解一下promise的原理promise的例子: 1. 接下来一步步实现一个简单的promise step1:promise 接受一个函数作为构造函数的参数,是立即执行的,并 ...

  6. 一步步学会用docker部署应用(nodejs版)

    一步步学会用docker部署应用 docker是一种虚拟化技术,可以在内核层隔离资源.因此对于上层应用而言,采用docker技术可以达到类似于虚拟机的沙盒环境.这大大简化了应用部署,让运维人员无需陷入 ...

  7. 一起学习造轮子(一):从零开始写一个符合Promises/A+规范的promise

    本文是一起学习造轮子系列的第一篇,本篇我们将从零开始写一个符合Promises/A+规范的promise,本系列文章将会选取一些前端比较经典的轮子进行源码分析,并且从零开始逐步实现,本系列将会学习Pr ...

  8. ES6语法(3)—— 用promise()对象优雅的解决异步操作

    Promise 是异步编程的一种解决方案,比传统的解决方案——回调函数和事件——更合理和更强大. 所谓Promise,简单说就是一个容器,里面保存着某个未来才会结束的事件(通常是一个异步操作)的结果. ...

  9. ES6之Promise用法详解

    一 前言 本文主要对ES6的Promise进行一些入门级的介绍.要想学习一个知识点,肯定是从三个方面出发,what.why.how.下面就跟着我一步步学习吧~ 二 什么是Promise 首先是what ...

随机推荐

  1. css 射线实现方法

    一个斜的四边形 .top_ad_out::before { content: ''; position: absolute; z-index: -1; width: 336px; height: 25 ...

  2. 【算法题】- 求和等于K子数组

    一整数(有正有负)数组,用尽量少的时间计算数组中和为某个整数的所有子数组 public class SumK { public static void main(String[] args) { in ...

  3. R语言---热图的制作

    >install.packages("gplots") > library("gplots")> p <- data.frame(rea ...

  4. javascript 原生方法监听DOM结构改变事件

    js原生方法监听DOM结构改变事件 document.addEventListener('DOMNodeInserted',function(){alert(1)},false);document.a ...

  5. Flex通过Blazeds利用Remoteservice与后台java消息推送

    http://www.cnblogs.com/xia520pi/archive/2012/05/26/2519343.html http://computerdragon.blog.51cto.com ...

  6. 20.allegro.铺铜[原创]

    1.内层铺铜 --- ---- 选择复制对象 ---- ----- ---- ------ --- --- --- 2.外层铺铜 -- -- 假如没有指定网络: 给这块没有网络的铜皮指定网络 --- ...

  7. [POJ1159]Palindrome(dp,滚动数组)

    题目链接:http://poj.org/problem?id=1159 题意:求一个字符串加多少个字符,可以变成一个回文串.把这个字符串倒过来存一遍,求这两个字符串的lcs,用原长减去lcs就行.这题 ...

  8. 《OD学hadoop》第三周0709

    一.MapReduce编程模型1. 中心思想: 分而治之2. map(映射)3. 分布式计算模型,处理海量数据4. 一个简单的MR程序需要制定map().reduce().input.output5. ...

  9. 3D场景优化

    一) 有效的性能评测 对于任何一个3D应用程序来说,追求场景画面真实感是一个无止尽的目标,其结果就是让我们的场景越来越复杂,模型更加精细,这必然给图形硬件带来极大的负荷以致于无法达到实时绘制帧率.因此 ...

  10. 宏ut_mem_block_t

    /** This struct is placed first in every allocated memory block */ typedef struct ut_mem_block_struc ...