让我们考虑一个具体的例子:我的存储库上返回Future
的方法(因为调用远程数据库需要花费时间并且可能会失败)
def findA(id: String) : Future[Option[String]] = ???
def findB(id: String) : Future[Option[String]] = ???
我需要一种结合它们的服务。此外,还有一个业务规则:两个ID必须与现有对象相对应,否则,程序必须快速失败并出现全面错误。
我基本上有两个选择:
仅使用Future
def findAll(idA: String, idB: String): Future[(String, String)] =
for {
a <- findA(idA).flatMap(_.fold(Future.failed[String](new RuntimeException("a not found")))(s => Future.successful(s)))
b <- findB(idB).flatMap(_.fold(Future.failed[String](new RuntimeException("b not found")))(s => Future.successful(s)))
} yield (a, b)
使用EitherT
def findAll(idA: String, idB: String): DisjunctionT[Future, String, (String, String)] =
for {
a <- EitherT(findA(idA).map(_.\/>("a not found")))
b <- EitherT(findB(idB).map(_.\/>("b not found")))
} yield (a, b)
使用EitherT
,我看到2个职业
还有其他优点和缺点吗?