2014-12-02 89 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