2015-11-03 39 views
1

因此...可以說我有一個Future[ List[ A ] ],我想要的是一個Future,其中包含所包含的listfirst element從未來[列表[A]]得到未來的首選方式

考慮到這是db訪問層的一部分,可以這樣做的首選方式是什麼?

def getFirstByName(name: String): Future[ A ] = { 
    val aListFuture = ... 
    // somehow got the future of list of all A's for this name 
    // Now how do I return a Future[ A ] contaning the head of said list 
} 

這個問題的焦點更多的是對Considering this is a part of the db access layer what can be the preferred way of doing this ?

我們可以按照如下方法做val aFuture = aListFuture.map(l => l.head),但如果列表爲空,該怎麼辦?

在這個問題中,我真正在尋找的是「如何設計一個可預測的解決方案?」。

是否有任何其他選擇而不是優雅地失敗與域特定異常?如果不是,我該如何實施這樣的失敗?

我目前使用這個下面骯髒的伎倆,

def getFirstByName(name: String): Future[ A ] = { 
    // somehow got the future of list of all A's for this name 
    val aListFuture = ... 
    aListFuture map(_.head) match { 
    case Some(t: Try[ A ]) => t match { 
     case Success(a: A) => Promise.successful(a).future 
     case Failure(e: NoSuchElementException) => Promise.failed(DbNotFound).future 
     case Failure(e) => Promise.failed(e).future 
    } 
    case _ => Promise.failed(new Exception("Some unexplained exception")).future 
    } 
} 
+0

爲什麼不改變函數的返回類型? –

+0

@FatihDonmez呃......這個問題本身就是一個錯誤。我需要這樣做。 –

+0

考慮如果列表爲空則該怎麼辦。 –

回答

2

試試這個:

val futureOfHead = aListFuture.map (_.head) 

對於情況時,未來的回報空的列表,你可以提供默認值:

val DefaultValue = ... 
val futureOfHead = aListFuture.map (_.headOption.getOrElse(DefaultValue)) 

另一種選擇:

val futureOfHead = aListFuture.map (_.headOption.getOrElse(throw new RuntimeException("db layer exception")) 
+0

好吧......但這不是非常不可預測的。如果清單是空的呢? l。在一張空白名單上l不能說非常明智,對嗎?你將如何從此恢復? –

+0

沒錯,但這取決於你如何處理這種情況。一種選擇是提供默認值。 – Nyavro

+0

查看我的上次編輯 – Nyavro

1

您可以使用map,然後使用head

def map[S](f: (T) ⇒ S)(implicit executor: ExecutionContext): Future[S] 

通過應用功能,這個未來的成功結果創建一個新的未來。如果這個未來完成了一個例外,那麼新的未來也將包含這個例外。

val aListFuture = futureList.map(l => l.head) 

此道的來電可以處理SuccessFailure

future.onComplete({ 
    case Success(result) => .. 
    case Failure(err) => .. //if head is empty you'll get java.util.NoSuchElementException 
} 
+0

好吧......但這不是非常不可預測的。如果清單是空的呢? 'l.head'在空列表'l'上不能說是非常明智的,對吧?你將如何從此恢復? –

+0

假設調用者已經有一個需要'Future [A]'的合同,該怎麼辦? –

+0

然後,您應該使用headOption.getOrElse並在應用程序環境中決定您的默認情況。 –

1

所有anwsers是真實的,但有可能是這樣的不易出錯的解決方案,如果配合您的問題:

val aListFuture = futureList.map(l => l.headOption) 

它返回的Future [Option [A]]可以通過模式匹配檢查。

另外,如果你想和對此有一個默認值,你可以使用:

val aListFuture = futureList.map(l => l.headOption.getOrElse("")) 
+0

不確定這種方法不「強大」,它是在列表頭部表示值的正確類型安全方法。 –