![](/img/trans.png)
[英]Scala collections: util.Map[String, AnyRef] - Map[String, String]
[英]Scala resolve multiple Futures and get a Map(String, AnyRef)
我目前正在嘗試一次解決多個期貨,但是由於其中一些可能會失敗,因此如果其中一個失敗,我不想全部失敗,而是以Map(String, AnyRef)
(意味着使用將來的名稱進行映射,並將響應轉換為所需的名稱)。
目前,我有以下內容:
val fsResp = channelList.map {
channelRef => channelRef.ask(ReportStatus).mapTo[EventMessage]
}
Future.sequence(fsResp).onComplete{
case Success(resp: Seq[EventMessage]) =>
resp.foreach { event => Supervisor.foreach(_ ! event) }
val channels = loadConfiguredComponents()
.collect {
case ("processor" | "external", components) => components.map {
case (name, config: Channel) =>
(name, serializeDetails(config, resp.find(_.channel == ChannelName(name))))
}
}.flatten.toMap
val event = EventMessage(...)
Supervisor.foreach(_ ! event)
case Failure(exception) => originalSender ! replayError(exception.getMessage)
}
但是,如果其中任何一個失敗,則此操作將失敗。 那么,如何才能得到Map(channelRef.path.name, event() | exception)
?
謝謝!
您可以使用fallbackTo以避免失敗。 在此示例中,我將Future [T]更改為Future [Option [T]],以回退到None,然后刪除None元素。
import scala.concurrent.ExecutionContext.Implicits.global
def method(value:Int) = { Thread.sleep(2000); println(value); value }
println("start")
val eventualNone = Future.successful(None)
val futures = List(Future(method(1)), Future(method(2)), Future(method(3)), Future(throw new RuntimeException))
val withoutFailures = futures.map(_.map(Option.apply).fallbackTo(eventualNone))
Future.sequence(withoutFailures).map(_.flatten).onComplete {
case Success(values) => println(values)
case Failure(ex:Throwable) => println("FAIL")
}
Thread.sleep(5000)
產量
start
1
3
2
List(1, 2, 3)
如果您想知道失敗的原因,可以將其更改為Either [Throwable,T]而不是Option [T]。
此代碼始終為Success(關於Future結果),因此您需要檢查您的值以了解所有期貨是否失敗。
要從Future列表中捕獲成功/失敗的值,您可以首先將map/recover
應用於每個值,然后使用Future.sequence
將結果列表轉換為Future的List[Either[Throwable,EventMessage]]
,如圖所示在下面的簡單示例中:
import scala.concurrent.{Future, Await}
import scala.concurrent.duration._
import scala.concurrent.ExecutionContext.Implicits.global
case class EventMessage(id: Int, msg: String)
val fsResp = List(
Future{EventMessage(1, "M1")}, Future{throw new Throwable()}, Future{EventMessage(3, "M3")}
)
val f = Future.sequence(
fsResp.map( _.map{ resp =>
// Do stuff with `resp`, add item to `Map()`, etc ...
Right(resp)
}.
recover{ case e: Throwable =>
// Log `exception` info, etc ...
Left(e)
} )
)
Await.result(f, Duration.Inf)
// f: scala.concurrent.Future[List[Product with Serializable with scala.util.
// Either[Throwable,EventMessage]]] = Future(Success(List(
// Right(EventMessage(1,M1)), Left(java.lang.Throwable), Right(EventMessage(3,M3))
// )))
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.