1
case object getValues
case class Data(a: Any, b:Any)

class Testing extends Actor {
def receive = {
case "do something" => {
  val result2 = { User.getList }
  sender ! result2
}
case _ => println("done")
}
}

class Testing2 extends Actor {
def receive = {
case getValues =>
  val result2 = { User.getMap }
   }yield Data(a,b)
  val child = context.actorOf(Props[Testing], "child")//creating actor
  implicit val askTimeout = Timeout(1.second)//giving timeout
  val r = child ? "do something"
  val res = for {
    a <- r
  } yield (a)
  res map (p=>sender ! Data(p, result2))//sending response to the sender
}
}

//Controller
object Application extends Controller {

def testingActor2 = Action.async {
val system = ActorSystem("ActorSystem")
val actor1 = system.actorOf(Props[Testing2], "Testing2")
implicit val askTimeout = Timeout(1.second)
val res = actor1 ? getValues
implicit val formats = DefaultFormats
val result = for {
  r1 <- res
} yield r1
result map (r => { println(r); Ok("got result") })
}

我无法将两个参与者的结果都交给控制器。如果我必须获取他们的结果然后将响应发送到页面,请告诉我如何使用演员。

4

2 回答 2

3
val f1 = Future(1) //ask first actor
  val f2 = Future(2) //ask second actor

  Future.sequence(List(f1, f2)).map(list => {
    //we got List[Int] here
    list
  })
于 2013-10-12T11:39:35.957 回答
2

我可以在您的代码中看到一个问题,它可能不是全部问题,在 中Testing2,您正在关闭sender可变的并且可能导致问题。原因是,当 asyncmap在 上运行时Futuresender可能已经更改为不同的ActorRef或可能被取消(切换到死信演员 ref),无论哪种方式,您都不会将响应返回到您想要的位置去。您只需执行以下操作即可解决此问题:

...
val res = for {
  a <- r
} yield (a)
val originator = sender
res foreach (p=>originator ! Data(p, result2))//sending response to the sender

或者您可以导入pipeTo模式并这样做:

import akka.pattern.pipeTo
...
val res = for {
  a <- r
} yield (a)
res map (p=> Data(p, result2)) pipeTo sender
于 2013-10-13T12:12:39.213 回答