【问题标题】:Use combineLatest with an array of observables将 combineLatest 与一组可观察对象一起使用
【发布时间】:2019-06-14 07:05:08
【问题描述】:

我有 4 个文本输入字段。当用户在任何字段中输入文本时,我将启用一个按钮。为此,我将通过组合 4 个在其流中接收文本的 observables 来使用 combineLatest。我不知道如何访问每个 observables 的最新值。注意:我想使用一个数组,因为最终会有超过 4 个输入字段。我也在寻找 Kotlin 的解决方案。

val text1: PublishSubject<String> = PublishSubject.create()
val text2: PublishSubject<String> = PublishSubject.create()
val text3: PublishSubject<String> = PublishSubject.create()
val text4: PublishSubject<String> = PublishSubject.create()

val inputs = Arrays.asList(
    text1, text2, text3, text4
)

Observable.combineLatest(inputs) {
  // How do I access the latest value from each observable?
}

【问题讨论】:

    标签: kotlin rx-java2


    【解决方案1】:

    在 lambda 中,您会得到一个数组。该数组的第 i 个元素(以下示例中为 arrayOfEmissions)对应于第 i 个 observable 发出的最新元素。

    Observable.combineLatest(inputs) { arrayOfEmissions ->
    }
    

    【讨论】:

    • 这不清楚。根据reactivex.io/documentation/operators/combinelatest.html 的弹珠图,我应该能够从每个可观察对象中获取最新值,根据它们的值做出决定,然后返回一个可观察对象。 combineLatest 大概为我提供了来自每个单独流的最新值。但我仍然需要访问每个发出的项目的值。只是不确定如何访问这些值。
    • 那些发出的项目在arrayOfEmissions
    • 你是对的。让代码工作后,我注意到虽然 arrayOfEmissions 确实包含值,但由我的代码来确定哪个数组项对应于文本输入字段。
    【解决方案2】:

    您可以组合它们并提供一个函数来将值包装到自定义类中:

        Observable.combineLatest(
                text1,
                text2,
                text3,
                text4,
                Function4<String, String, String, String, LatestResult> { t1, t2, t3, t4 ->
                    LatestResult(t1, t2, t3, t4)
                })
                .subscribe { latestResult ->
                    // Access the latest results here:
                    println(latestResult.text1)
                    println(latestResult.text2)
                    println(latestResult.text3)
                    println(latestResult.text4)
                }
    }
    
    data class LatestResult(val text1: String, val text2: String, val text3: String, val text4: String)
    

    【讨论】:

      【解决方案3】:

      你可以使用这些extension functions

      // [publisher1, publisher2].combineLatest()
      extension Array where Element: Publisher {
          func combineLatest() -> AnyPublisher<[Element.Output], Element.Failure> {
              Publishers.CombineLatestArray(self)
          }
      }
      
      // Publishers.CombineLatestArray([publisher1, publisher2])
      extension Publishers {
          static func CombineLatestArray<P>(_ array: [P]) -> AnyPublisher<[P.Output], P.Failure> where P : Publisher {
              array.dropFirst().reduce(into: AnyPublisher(array[0].map{[$0]})) { res, ob in
                  res = res.combineLatest(ob) { i1, i2 -> [P.Output] in
                      return i1 + [i2]
                  }.eraseToAnyPublisher()
              }
          }
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-12-11
        • 1970-01-01
        • 1970-01-01
        • 2019-08-06
        • 2022-01-23
        相关资源
        最近更新 更多