我试图让代码在特定的用户操作上执行某种可失败的长时间运行请求,但是在请求处于活动状态时忽略可悲的操作。目标是允许点击按钮,只要没有成功的排放来自请求。跳过所有错误。到目前为止,我开始编写这样的代码,但不知道下一步该做什么:
struct ErrorError: Error {}
var emitSuccess: Bool = false
// should be something like button.rx.tap
let buttonTap = PublishSubject<Void>()
let requestDuration: RxTimeInterval = 5
let tapInterval: RxTimeInterval = 3
let requestTrigger = buttonTap
// ???
.flatMapLatest { (_) -> Observable<Bool> in
// imitation of http request/parsing etc.
if emitSuccess {
return Observable.just(true)
.delay(requestDuration, scheduler: MainScheduler.instance)
.debug("response success", trimOutput: false)
} else {
emitSuccess = true
return Observable.error(ErrorError())
.materialize()
.delay(requestDuration, scheduler: MainScheduler.instance)
.dematerialize()
.debug("response failure", trimOutput: false)
.catchErrorJustComplete()
}
}
.take(1) //supposed to dispose observation of taps
.share(replay: 1, scope: .forever)
let requestResponse = requestTrigger
.debug("response", trimOutput: false)
.subscribe()
// imitate button tap
Observable<Int>.interval(tapInterval, scheduler: MainScheduler.instance)
.takeUntil(Observable.just(true).delay(20, scheduler: MainScheduler.instance))
.debug("button tap imitation", trimOutput: false)
.subscribe(onNext: { (value) in
buttonTap.onNext(())
return
})在目前的形式下,每个水龙头都会处理未完成的、可观察到的,并启动一个新的,这是不可取的。“??”是我认为应该是一些聪明的节流/跳过操作符的地方。
脑海中浮现的事物:
takeUntil(requestResponse),这会导致某种奇怪的递归订阅(甚至允许/好/坏的做法?)concatMap而不是flatMapLatest,但它类似于队列访问,在本例中,如果出现错误(例如,没有互联网连接),它可能会发生在所有排队的taps ->请求中,这意味着我需要跳过抽头。create、deferred等)发布于 2019-04-01 17:17:55
这个问题的答案是表面上的--我应该直接使用flatMapFirst。在我看来,许多rx操作符的含义和用例都不明显,最好的方法就是练习和阅读。
顺便说一句,这个漂亮的柱子 --尽管有些重复的文档--对我来说还是稍微好一些,而且在写完这个问题(facepalm) 10分钟后,我就读到了这个问题(虽然我可以只阅读所有操作符的文档,并最终找到我需要的)。
https://stackoverflow.com/questions/55459969
复制相似问题