在我的演员中,我在不同的地址有两个请求:
http.singleRequest(HttpRequest(uri = encodedUri).addHeader(Accept(MediaTypes.`application/json`)))
我需要这两个请求都返回一个值。作为正常的未来,我期待这样的事情:
val response: Future[SomeData] = for {
r1 <- firstRequest
r2 <- secondRequest
} yield {
// merge the results of these two responses
}
response onComplete {
case Success(body) => sndr ! Something(body)
case Failure(message) => BadRequest(message.toString)
}
在文档的这一部分:
http://doc.akka.io/docs/akka/2.4/scala/http/client-side/request-level.html
建议使用pipeTo
至self
来管理单个请求,而不是使用原生onComplete/map/etc
。
如何在多个请求中应用该请求,例如我需要等待2个或更多个请求才能完成?
答案 0 :(得分:3)
简单而直接的
val f1 = Future { //request1 }
val f2 = Future { //request2 }
val resultF = f1 zip f2
resultF pipeTo self
当前演员将获得结果作为消息,消息将是元组(f1Result, f2Result)
如果结果resultF
失败,则当前的actor获取包含在akka.actor.Status.Failure
方法f1
和f2
是独立期货
如果f2
取决于f1
使用flatMap
val resultF = f1.flatMap { f1Result => createF2(f1Result) }
//alternatively we can use for comprehension
resultF pipeTo self
示例强>
import akka.actor.Actor
import akka.actor.Status.Failure
import scala.concurrent.Future
import akka.pattern.pipe
object ManagerActor {
case object Exec
}
class ManagerActor extends Actor {
import ManagerActor._
implicit val dispather = context.dispatcher
override def receive: Receive = {
case Exec =>
val f1 = Future { 1 }
val f2 = Future { 2 }
val resultF = f1 zip f2
resultF pipeTo self
case result: (Int, Int) => //be careful about type erasure
println(s"""result:$result""")
case Failure(th) =>
println(s"""msg: ${th.getMessage}""")
}
}
运行
object Main {
def main(args: Array[String]): Unit = {
val system = ActorSystem()
val actor = system.actorOf(Props[ManagerActor])
actor ! ManagerActor.Exec
Thread.sleep(1000000)
}
}
我们可以使用Future.sequence
代替zip
将此概括为任意数量的http请求。