使用最后一个中的第一个结果,依次运行3个可观察物

时间:2018-10-01 11:41:34

标签: ios swift rx-swift

上下文

我想使用RxSwift依次运行3种不同的操作:

  1. 获取产品
  2. 完成产品提取后,删除缓存
  3. 删除缓存后,请使用步骤1
  4. 中的产品保存新的缓存

这些是我的服务中的函数定义:

struct MyService {

  static func fetchProducts() -> Observable<[Product]> {...}
  static func deleteCache() -> Observable<Void> {...}
  static func saveCache(_ products: [Product]) -> Observable<Void> {...}

}

我通常使用flatMapLatest实现该行为。

但是,用这种方法,我将丢失第一个可观察的([Product])的结果,因为中间(deleteCache)的操作不接收参数,并在完成时返回Void。< / p>

struct CacheViewModel {


  static func refreshCache() -> Observable<Void> {
    return MyService.fetchProducts()
      .flatMapLatest { lostProducts in MyService.deleteCache() }
      .flatMapLatest { MyService.saveCache($0) } // Compile error*
  }
  // * Cannot convert value of type 'Void' to expected argument type '[Product]'

}

编译错误是绝对公平的,因为中间的操作会“破坏”第一个结果的传递链。

问题

目前有什么机制可以使用RxSwift来实现此串行执行,并累积先前操作的结果?

3 个答案:

答案 0 :(得分:1)

        service
            .fetchProducts()
            .flatMap { products in
                return service
                    .deleteCache()
                    .flatMap {
                       return service
                        .saveCache(products)
                    }
            }

答案 1 :(得分:0)

最简单的解决方案是,在第二个Observable<Products>内使用Rx框架just中的静态方法,返回一个flatMap()类型的新Observable,并传递{{1 }}是您在flatmap-closure中捕获的,即:

lostProducts

这样,您就不会丢失flatMap中第一次调用的结果,而只是在清除缓存后才将其传递通过。

答案 2 :(得分:0)

您可以使用do(onNext:)删除缓存数据,然后在flatMapLatest中保存产品。可选的SaveCacheDeleteCache返回Completable,以便在保存或删除操作失败时可以处理错误。

struct CacheViewModel {

    static func refreshCache() -> Observable<Void> {
        return MyService.fetchProducts()
            .do(onNext: { _ in
                MyService.deleteCache()
            }).flatMap { products in
                MyService.saveCache(products)
            }
    }
}