簡體   English   中英

反應擴展(RxScala)等同於ifEmpty的倍數

[英]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")))
我想你想要`orElse [U>:T](默認值:⇒U):Observable [U]`getFooFromCache()。orElse(getFooFromDatabase())`(此方法與[equivalent](http:// reactivex .io / rxscala / comparison.html)(RxScala所基於的RxJava實現中的defaultIfEmpty(T))。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM