2016-08-10 97 views
0

我正在斯卡拉的期货周围慢慢地包裹着我的大脑,并有一点点的蛋糕正在尝试解开。在斯卡拉期货迷路

具体使用案例是 sangria-graphql + akka。我已经偷了他们的演示代码,它看起来像这样

Future.fromTry(Try(
    friendIds map (id => CharacterRepo.humans.find(_.id == id) orElse CharacterRepo.droids.find(_.id == id)))) 

,并加入我自己修改它。他们确实在内存中查找,而我的要求的另一位演员的东西:

Future.fromTry(Try(
    accountIds match { 
     case h :: _ => 
     val f = sender ? TargetedMessage(h) 
     val resp = Await.result(f, timeout.duration).asInstanceOf[TargetedMessage] 
     marshallAccount(resp.body) 

     case _ => throw new Exception("Not found") 
    } 
)) 

这里的相关部分是我挑的第一个元素在列表中,将其发送到ActorRef,我得到了其他地方,等待结果。这工作。我今天准备这样做,但是,是不是还得等待结果在这里,但回到整个事情的Future

Future.fromTry(Try(
    accountIds match { 
     case h :: _ => 
     sender ? TargetedMessage(h) map { 
      case resp:TargetedMessage => marshallAccount(resp.body) 
     } 

     case _ => throw new Exception("Not found") 
    } 
)) 

这是行不通的。当这个被消耗的,而不是Account型(功能marshallAccount返回类型,它的类型作出承诺。如果我理解正确的话,那是因为,而不是具有Future[Account]返回类型,这有一个类型的Future[Future[Account]]

如何拉平这个

回答

3

您正在寻找在错误的API方法Future.fromTry被用来创建一个立即解决的未来,这意味着通话实际上不是异步潜入Future.fromTry实施,这将带你到:。

def fromTry[T](result: Try[T]): Promise[T] = new impl.Promise.KeptPromise[T](result) 

一个承诺保存基本上是已经发生,所以就像Future.successful这只是用来确保正确的返回类型或类似的东西,它实际上并不是一种方法来做一些异步。

返回类型为Future[Future[Something]]的原因是因为您试图将已经返回未来的东西包装到另一个未来中。

的询问模式,即sender ? TargetMessage(h)是一种方法,一些演员和等待的结果,这将返回一个未来。

正确的方式来处理这个:

val future: Future[Account] = accountIds match { 
    case h :: _ => sender ? TargetedMessage(h) map (marshallAccount(_.body) 
    case _ => Future.failed(throw new Exception("Not found")) 
} 

基本上你需要使用Future.failed从异常返回失败的未来,如果你想保留的返回类型一致。值得回顾this tutorial以了解更多关于Futures的信息,以及如何使用它们编写应用程序逻辑。