Scala 从参与者返回将来的消息

Scala 从参与者返回将来的消息,scala,akka,scalaz,Scala,Akka,Scalaz,我有一个现有的API,它返回一个Future。现在为其中一个用例引入一个Actor,并尝试继续从中使用相同的服务API。从下面可以看到MyService.saveValuesreturnfuture object MyActor { implicit val ec = scala.concurrent.ExecutionContext.Implicits.global implicit val timeout = Timeout(1 second) case class Sam

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

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
也会创建自己的未来,因此
saveMessage
中的结果(
val res
)会变成
future[future[T]]
,看起来很烦人。处理这种情况的最佳方法是什么

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]
,你总是可以“平面映射那狗屎”

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

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