2014-12-02 54 views
1

我使用未来创建三个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)

+2

尝试在任何情况下,返回同一类型。您应该返回'Nil'而不是'None'或使用'Option [List [ResultData]]'。 – senia 2014-12-02 09:04:32

回答

3

你可以与NilmapTo之前更换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] 
+0

感谢您的好评。至于你对mapTo与List泛型的评论,你会推荐什么,而不是mapTo? – user3370773 2014-12-02 09:22:15

+0

@ user3370773:您可以使用'mapTo'而不是泛型类(请参阅更新)。问题不在'mapTo'方法中 - 你会在actor中的'receive'方法中遇到同样的问题。 – senia 2014-12-02 09:26:48