运行 连续 3 个 observable,在最后一个中使用第一个的结果
Run 3 observables sequentially, using result from first in the last one
上下文
我想 运行 使用 RxSwift 按顺序进行 3 个不同的操作:
- 获取产品
- 产品获取完成后,删除缓存
- 缓存删除完成后,使用步骤 1
中的产品保存新缓存
这些是我的服务中的函数定义:
struct MyService {
static func fetchProducts() -> Observable<[Product]> {...}
static func deleteCache() -> Observable<Void> {...}
static func saveCache(_ products: [Product]) -> Observable<Void> {...}
}
我通常使用 flatMapLatest
实现该行为。
但是,我会用这种方法丢失第一个可观察对象 ([Product]
) 的结果,因为中间的操作 (deleteCache
) 不接收参数并且 returns 完成后作废。
struct CacheViewModel {
static func refreshCache() -> Observable<Void> {
return MyService.fetchProducts()
.flatMapLatest { lostProducts in MyService.deleteCache() }
.flatMapLatest { MyService.saveCache([=12=]) } // Compile error*
}
// * Cannot convert value of type 'Void' to expected argument type '[Product]'
}
编译错误是绝对公平的,因为中间的操作 'breaks' 第一个结果的传递链。
问题
有什么机制可以用 RxSwift 实现这种串行执行,累积先前操作的结果?
最简单的解决方案是,在第二个 flatMap()
中使用 Rx 框架 just 中的静态方法 return 一个类型为 Observable<Products>
的新 Observable,传入您在平面图闭包中捕获的 lostProducts
,即:
static func refreshCache() -> Observable<Void> {
return MyService.fetchProducts()
.flatMapLatest { lostProducts -> Observable<[Product]> in
MyService.deleteCache()
return Observable.just(lostProducts)
}
.flatMapLatest { MyService.saveCache([=10=]) } // No compile error
}
这样你就不会丢失 flatMap 中第一次调用的结果,而只是在清除缓存后传递它。
您可以使用do(onNext:)
删除缓存数据,然后在flatMapLatest中您可以保存产品。可选 SaveCache
和 DeleteCache
应该 return Completable
以便您可以在保存或删除操作失败时处理错误。
struct CacheViewModel {
static func refreshCache() -> Observable<Void> {
return MyService.fetchProducts()
.do(onNext: { _ in
MyService.deleteCache()
}).flatMap { products in
MyService.saveCache(products)
}
}
}
service
.fetchProducts()
.flatMap { products in
return service
.deleteCache()
.flatMap {
return service
.saveCache(products)
}
}
上下文
我想 运行 使用 RxSwift 按顺序进行 3 个不同的操作:
- 获取产品
- 产品获取完成后,删除缓存
- 缓存删除完成后,使用步骤 1 中的产品保存新缓存
这些是我的服务中的函数定义:
struct MyService {
static func fetchProducts() -> Observable<[Product]> {...}
static func deleteCache() -> Observable<Void> {...}
static func saveCache(_ products: [Product]) -> Observable<Void> {...}
}
我通常使用 flatMapLatest
实现该行为。
但是,我会用这种方法丢失第一个可观察对象 ([Product]
) 的结果,因为中间的操作 (deleteCache
) 不接收参数并且 returns 完成后作废。
struct CacheViewModel {
static func refreshCache() -> Observable<Void> {
return MyService.fetchProducts()
.flatMapLatest { lostProducts in MyService.deleteCache() }
.flatMapLatest { MyService.saveCache([=12=]) } // Compile error*
}
// * Cannot convert value of type 'Void' to expected argument type '[Product]'
}
编译错误是绝对公平的,因为中间的操作 'breaks' 第一个结果的传递链。
问题
有什么机制可以用 RxSwift 实现这种串行执行,累积先前操作的结果?
最简单的解决方案是,在第二个 flatMap()
中使用 Rx 框架 just 中的静态方法 return 一个类型为 Observable<Products>
的新 Observable,传入您在平面图闭包中捕获的 lostProducts
,即:
static func refreshCache() -> Observable<Void> {
return MyService.fetchProducts()
.flatMapLatest { lostProducts -> Observable<[Product]> in
MyService.deleteCache()
return Observable.just(lostProducts)
}
.flatMapLatest { MyService.saveCache([=10=]) } // No compile error
}
这样你就不会丢失 flatMap 中第一次调用的结果,而只是在清除缓存后传递它。
您可以使用do(onNext:)
删除缓存数据,然后在flatMapLatest中您可以保存产品。可选 SaveCache
和 DeleteCache
应该 return Completable
以便您可以在保存或删除操作失败时处理错误。
struct CacheViewModel {
static func refreshCache() -> Observable<Void> {
return MyService.fetchProducts()
.do(onNext: { _ in
MyService.deleteCache()
}).flatMap { products in
MyService.saveCache(products)
}
}
}
service
.fetchProducts()
.flatMap { products in
return service
.deleteCache()
.flatMap {
return service
.saveCache(products)
}
}