返回演员的未来消息

时间:2014-07-07 19:54:34

标签: scala akka scalaz

我有一个API,它会返回Future。现在为其中一个用例引入Actor并尝试继续使用相同的服务API。从下面您可以看到MyService.saveValues返回未来。

object MyActor {
   implicit val ec = scala.concurrent.ExecutionContext.Implicits.global
   implicit val timeout = Timeout(1 second)
   case class SampleMessage(list: List[String])
   val actorSystem =  //get actorSystem that was created at the startup


  def saveMessage(list: List[String])  ={
    val res = (actorSystem.actorOf(Props[MyActor]) ? SaveMyMessage(list) ).mapTo[Future[\/[Throwable,String]]
 //res map{ r=>

 //}

 }
}
class MyActor extends Actor {
import MyActor._

def receive = {
  case SaveMyMessage(list) =>

   val originalSender = sender

   val res : Future[\/[Throwable,String] ] = MyService.saveValues(list)


   originalSender ! res
  }
}

正如您在def saveMessage中所看到的,我正在使用ask等待演员的结果。但是,ask也会创建自己的未来,因此val res中的结果(saveMessage)变为Future[Future[T]],这看起来很烦人。处理这种情况的最佳方法是什么?

1 个答案:

答案 0 :(得分:7)

pipeTo将未来的结果转发给ActorRef

import akka.pattern.pipe


val originalSender = sender
val res : Future[\/[Throwable,String] ] = MyService.saveValues(list)
res pipeTo originalSender

如果saveValues抛出,你的未来永远不会完成,但最终还会计划出来。

如果您最终得到Future[Future[A]],但由于Future[A]或某事需要sequencing/traversing,您可以随时“flatMap that that shit。”

import ExecutionContext.Implicits.global
val foo: Future[Future[Int]] = ???
val bar: Future[Int] = foo.flatMap(identity)

如果你已经依赖scalaz(以及scalaz.contrib,如果在scalaz 7.0.x上),你可以使用monad语法中定义的join

import scalaz.syntax.monad._
import scalaz.contrib.std.scalaFuture._
val bar2: Future[Int] = foo.join