Future [Option [T]]:如果定义了Option,则保留未来,否则回退到另一个未来

时间:2019-09-18 10:20:21

标签: scala future

我有这个val cacheElement:Future[Option[T]],并且如果OptionSome,则期望的结果是保留未来;如果未来是,则基于其他服务创建另一个Future[Option[T]] None。使用模式匹配看起来像这样:

val cacheElement:Future[Option[T]] = cache.get[T](cacheKey)

for {
    opt <- cacheElement flatMap {
        case Some(cached) => Future { Some(cached) } 
        case None => createFallback(args)
           }
} yield { opt match {
        case Some(_) => //do something
        case None => // Do something else   
    }
}


def createFallback[T](args:T):Future[Option[T]] = ???-

我该如何以更优雅和更轻松的方式做到这一点? Future { Some(cached) }的重复在我看来非常冗长

2 个答案:

答案 0 :(得分:3)

import scala.concurrent.Future
import scala.concurrent.Await
import scala.concurrent.ExecutionContext.Implicits.global
import scala.concurrent.duration._

type T = String

val cacheElement: Future[Option[T]] = Future.successful(Some("asd"))
val failElement: Future[Option[T]] = Future.successful(None)

def createFallback: Future[T] = Future.successful("fallback")

val s = cacheElement.flatMap(_.fold(createFallback)(Future.successful))
val f = failElement.flatMap(_.fold(createFallback)(Future.successful))

Await.result(s, 1.second)
//res0: T = asd
Await.result(f, 1.second)
//res1: T = fallback

答案 1 :(得分:2)

OptionT来自cats的monad转换器提供了orElse这样的语法

OptionT(cacheElement) orElse OptionT(createFallback(args))

例如

import cats.data.OptionT
import cats.implicits._
import scala.concurrent.ExecutionContext.Implicits.global
import scala.concurrent.Future

object OptionTExample extends App {
  val f: Future[Option[Int]] = Future(None)
  def fallback: Future[Option[Int]] = Future(Some(-1))
  val v = OptionT(f) orElse OptionT(fallback)
  v.value.map(println)
}

输出

Some(-1)