Scala Future with Option()
我使用未来创建三个actor任务,然后在完成时尝试收集所有三个任务。 当前的代码如下:Scala Future with Option()
implicit val timeout = Timeout(5.seconds)
val result1 = actor1 ? DataForActor(data)
val result2 = actor2 ? DataForActor(data)
val result3 = actor3 ? DataForActor(data)
val answer = for {
a <- result1.mapTo[List[ResultData]]
b <- result2.mapTo[List[ResultData]]
c <- result3.mapTo[List[ResultData]]
} yield (a ++ b ++ c).sorted
answer onComplete {
case Success(resultData) =>
log.debug("All actors completed succesffully")
successActor ! SuccessData(resultData.take(2))
case Failure(resultData) =>
log.info("actors failed")
}
每个参与者(actor1,actor2,actor3)操纵数据并返回无或选项(列表(resultData)),如图所示在下面的代码的:
val resultData = if(data.size == 0) None else {
data.map {
...
try {
... //manipulation on resultData
Option(resultData)
}
catch {
case e: Exception => None
}
}.flatten
}
for语句连接来自每个actor的列表,并生成一个long List(resultData)。
我希望在一个actor返回None的情况下,它的结果是for语句不会向串联添加任何内容,即List()。
一个例子:
如果我得到: RESULT1 =列表(1,2,3), RESULT2 =无, result3 =列表(4,5),
我想: resultData =列表(1,2,3,4,5)
你可以与Nil
mapTo
之前更换None
这样:
result1.map{
case None => Nil
case x => x
}.mapTo[List[ResultData]]
需要注意的是,你应该避免mapTo
与泛型类型像List
:
Future("x" :: Nil).mapTo[List[Int]]
// res0: scala.concurrent.Future[List[Int]]
Future("x" :: Nil).mapTo[List[Int]] foreach { _.map(_ + 1) }
// java.lang.ClassCastException: java.lang.String cannot be cast to java.lang.Integer
因为类型擦除mapTo
不能证明你有Int
名单,一些其他类型的不List
。你会得到与case l: List[Int]
相同的问题receive
演员的方法。
您应该为您的短信像这样创建特殊类:
sealed trait ResultList { def data: List[ResultData] }
case class NotEmptyResult(data: List[ResultData]) extends ResultList
case object EmptyResult extends ResultList { def data: List[ResultData] = Nil }
result1.mapTo[ResultList]
感谢您的好评。至于你对mapTo与List泛型的评论,你会推荐什么,而不是mapTo? – user3370773 2014-12-02 09:22:15
@ user3370773:您可以使用'mapTo'而不是泛型类(请参阅更新)。问题不在'mapTo'方法中 - 你会在actor中的'receive'方法中遇到同样的问题。 – senia 2014-12-02 09:26:48
尝试在任何情况下,返回同一类型。您应该返回'Nil'而不是'None'或使用'Option [List [ResultData]]'。 – senia 2014-12-02 09:04:32