最近在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. PowerDesigner-自定义生成WORD

    PowerDesigner-自定义生成WORD_旧梦重温 分类: web 2014-02-26 21:08 1563人阅读 评论(48) 收藏 举报   目录(?)[+] 1统一建立模型 2导出自定义 ...

  2. linux 僵死进程

    僵死进程简而言之就是:子进程退出时,父进程并未对其发出的SIGCHILD信号进行适当处理,导致子进程停留在僵死状态等待其父进程为其收尸,这个状态下的子进程就是僵死进程. 在fork()/execve( ...

  3. linux常用头文件及说明

    linux常用头文件及说明 1. Linux中一些头文件的作用: <assert.h>:ANSI C.提供断言,assert(表达式)<glib.h>:GCC.GTK,GNOM ...

  4. JS里面匿名函数的调用 & 变量作用域的实验

    参考 http://www.educity.cn/wenda/54753.html 已实验验证结果正确. 1.下列哪些正确?(B.C) A.function(){ alert("Here!& ...

  5. POJ (线段树) Who Gets the Most Candies?

    这道题综合性挺强的,又牵扯到数论,又有线段树. 线段树维护的信息就是区间中有多少个人没跳出去,然后计算出下一个人是剩下的人中第几个. 我在这调程序调了好久,就是那个模来模去的弄得我头晕. 不过题确实是 ...

  6. HDU 2144 (最长连续公共子列 + 并查集) Evolution

    我发现我一直理解错题意了,这里的子序列指的是连续子序列,怪不得我写的LCS一直WA 顺便复习一下并查集 //#define LOCAL #include <iostream> #inclu ...

  7. HDU 1253 (简单三维广搜) 胜利大逃亡

    奇葩!这么简单的广搜居然爆内存了,而且一直爆,一直爆,Orz 而且我也优化过了的啊,尼玛还是一直爆! 先把代码贴上睡觉去了,明天再来弄 //#define LOCAL #include <ios ...

  8. 基于HtmlUnit的模板的网页数据抽取

    既然方向定了,就开始做实验室吧,做舆情分析,首先就是要收集相关的语料 正好实验室有同学在做标化院的信息抽取抽取这块 于是把程序拿过来研究研究正好 完整程序在126邮箱共享: 可下载数:20  共享连接 ...

  9. POJ 1422 Air Raid (最小路径覆盖)

    题意 给定一个有向图,在这个图上的某些点上放伞兵,可以使伞兵可以走到图上所有的点.且每个点只被一个伞兵走一次.问至少放多少伞兵. 思路 裸的最小路径覆盖. °最小路径覆盖 [路径覆盖]在一个有向图G( ...

  10. kthread_stop引起的OOP

    1 使用kthread_create创建线程:     struct task_struct *kthread_create(int (*threadfn)(void *data), void *da ...