最近在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,不过通过这种重新构造现有概念的方式(当然也是因为自己的无知- -)确实能够帮助对现有概念的理解。