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