Chain Scala期货回归类型

elm*_*lto 7 scala future

我试图在Scala中链接Futures,但它给了我错误的返回类型.

我有以下方法:

  def getOneRecordByModel(x:DirectFlight): Future[Option[FlightByDetailModel]] = {
    select.allowFiltering().where(_.from eqs x.from).and(_.to eqs x.to).and(_.departure eqs x.departure).and(_.arrival eqs x.arrival).and(_.carrier eqs x.airline).and(_.code eqs x.flightCode).one()
  }
  def getRecordByUUID(x:FlightByDetailModel): Future[Option[FlightByUUIDModel]] = {
    select.allowFiltering().where(_.uuid eqs x.uuid).one()
  }

  def getUUIDRecordByModel(x:DirectFlight): Future[Option[FlightByUUIDModel]] = {
      getOneRecordByModel(x) andThen {
        case Success(Some(flight)) => getRecordByUUID(flight)
        case Success(x) => Success(x)
        case Failure(x) => Failure(x)
      }
    }
Run Code Online (Sandbox Code Playgroud)

但现在我得到了getUUIDRecordByModel返回类型的错误Future[Option[FlightByDetailModel]]

我如何正确链接它们?

Mic*_*jac 8

我会flatMap改用.

def getUUIDRecordByModel(x:DirectFlight): Future[Option[FlightByUUIDModel]] = {
    getOneRecordByModel(x) flatMap {
        case Some(flight) => getRecordByUUID(flight)
        case None => Future.successful(None)
    }
}
Run Code Online (Sandbox Code Playgroud)

andThen应用副作用函数并返回原始 函数Future,而不是内部函数.


jor*_*an3 5

该解决方案及其上方的2实际上是相同的.他们提出了flatMaps组成的简单答案.这对于一次性解决方案很有用.

for {
   oUuid <- getOneRecordByModel(x)
   oFlight <- oUuid.map(getRecordByUUID).getOrElse(Future.successful(None))
} yield oFlight
Run Code Online (Sandbox Code Playgroud)

我怀疑给定方法签名,你将会使用这个策略很多.如果是这种情况,建议使用@Eugene Zhulenev上面的答案(这是一个更实用的解决方案).思想Monad变形金刚乍一看看起来有点令人生畏,这里有大量的代码:

val flightByUUID = for {
  flightByDetailModel <- optionT(getOneRecordByModel(x))
  flightByUUIDModel   <- optionT(getRecordByUUID(flightByDetailModel))
} yield flightByUUIDModel

flightByUUID.run  // this line grabs you a Future[Option[T]]
Run Code Online (Sandbox Code Playgroud)

当您开始增加复杂性时,非常简单,可扩展.希望这会对你有所帮助.