[英]Reactive Extensions (RxScala) equivalent of fold ifEmpty
我想知道是否存在與Scala折疊ifEmpty函數等效的集合和選項:
fold[B](ifEmpty: => B)(f: (A) => B)
該函數的強大之處在於它可以在不同的monad類型之間進行轉換-例如,以下代碼將Option [Person]轉換為Observable [Person]:
case class Person(name: String)
val observable = Option(Person("Paddy")).fold
{ Observable.just[Person]() } // ifEmpty function
{ p => Observable.just(p) }
我當前的問題是我希望在Reactive Extensions領域中找到類似的東西。 我的實際情況更多地要求“空時切換”類型的功能-理想情況下:
// getFooFromCache returns Observable[Foo] from some cache service
// getFooFromDatabase returns Observable[Foo] from some database service
val sourceObservable = getFooFromCache()
sourceObservable.switchIfEmpty { getFooFromDatabase() }
因此,這里的想法是,如果源可觀測對象完成並且什么都不發出,則“切換”到另一個可觀測對象。 如上面所建議的,是一個實際的示例-嘗試從緩存中獲取內容,如果沒有返回任何內容,則從數據庫中獲取內容。
我目前實現上述目標的方法如下:
getFooFromCache()
.map { Option(_) }
.orElse { None }
.flatMap {
case (Some(foo)) => Observable.just(foo)
case _ => getFooFromDatabase()
}
換句話說-將結果包裝在Option中(這樣可以將空結果作為None值發出),然后是帶有模式匹配的flatMap。
編輯:如果不存在,這是我將使用的幾個擴展功能:
object RxUtils {
implicit class RxUtilExtensions[+T](val observable: Observable[T]) extends AnyVal {
def toOption[U >: T]() : Observable[Option[U]] = {
observable
.map { Option(_) }
.orElse { None }
}
def switchIfEmpty[U >: T](f: () => Observable[U]) : Observable[U] = {
observable.toOption
.flatMap {
case(Some(t)) => Observable.just(t)
case _ => f()
}
}
}
}
有了以上內容,我現在可以執行以下操作:
getFooFromCache("item.id")
.switchIfEmpty { () => getFooFromDatabase("item.id") }
如果您使用的是RxScala 0.24,並且對使用“實驗性” API感到滿意,則可以
import rx.lang.scala.ExperimentalAPIs._
然后做
getFooFromCache("item.id").switchIfEmpty(getFooFromDatabase("item.id"))
請注意,該參數已被急切地評估,因此要獲得與您的解決方法相同的效果,您將需要執行
getFooFromCache("item.id").switchIfEmpty(Observable.defer(getFooFromDatabase("item.id")))
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.