簡體   English   中英

Scala與多個期貨合作

[英]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
}

然后我想返回兩個列表。 但是我不知道如何處理異常:

  1. db可能拋出連接不可用

  2. 遠程服務-錯誤的請求或InternalServer錯誤

  3. 兩者-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  => // ...
}

(組成例外的名稱)

您需要結合flatMaprecover

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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM