[英]Scala work with multiple futures
我有兩個返回List[Int]
的數據源
// first work with postgresql database
object Db {
def get: Future[List[Int]] = // impl
}
// second it's remote service
object Rs {
def get: Future[List[Int]] = // impl
}
然后我想返回兩個列表。 但是我不知道如何處理異常:
db可能拋出連接不可用
遠程服務-錯誤的請求或InternalServer錯誤
兩者-TimeoutException
但是,當我只有db的結果時,我想返回它。 如果我有數據庫和遠程服務的結果,我想返回兩個列表的和。
如何處理這種情況?
val total: Future[Int] =
Db.get.flatMap { dbResults =>
Rs.get.map { remoteResults =>
dbResults.sum + remoteResults.sum
}
}
或同等
val total: Future[Int] = for {
dbResults <- Db.get
remoteResults <- Rs.get
} yield dbResults.sum + remoteResults.sum
為了清楚起見,我明確注釋了結果類型,但這不是必需的。
total
是一個Future[Int]
其中包含成功或失敗的計算。 如果需要處理錯誤,可以在其上附加onFailure
處理程序。 例如
total.onFailure {
case e: TimeoutException => // ...
case e: ConnectionError => // ...
}
(組成例外的名稱)
您需要結合flatMap
和recover
:
for {
db <- Db.get
rs <- Rs.get.recover {
case e =>
logger.error("Error requesting external service", e)
List.fill(db.length)(0)
}
} yield (db, rs).zipped.map(_+_).sum
您可以根據需要調整轉換(我假設您的意思是列表的元素加和),但是基本思想保持不變-如果您要“忽略”某些將來的失敗,則需要對其進行調用recover
。
如果需要,您可以從中提取恢復函數以for
理解,但是仍然必須在其中調用recover
:
def handler(n: Int): PartialFunction[Throwable, List[Int]] = {
case e =>
logger.error("Error requesting external service", e)
List.fill(n)(0)
}
for {
db <- Db.get
rs <- Rs.get.recover(handler(db.length))
} yield (db, rs).zipped.map(_+_).sum
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.