我有一个向服务器发出API请求的函数。我想循环它直到它返回false
(没有更多的数据)。
func getData(id: Int) -> Observable<Bool> {
return Observable.create { observer in
// Alamofire request
// parse data
// if can decode,
// return true and increment page's property
// otherwise false
// error, if there's a problem
}
}
takeWhile
,例如:getData(id).takeWhile {$0}
。它只迭代我的函数1x。第二次尝试:使用范围。这里的问题是,即使我的getData
函数出错,而不是停止,循环仍然继续!
Observable.range(start: 1, count: 100)
.enumerated()
.flatMapLatest({ _ in
self.getData(someID)
})
.subscribe(onNext: { _ in
// save to DB
observer.onNext(true)
observer.onCompleted()
}, onError: { error in
observer.onError(error)
})
.disposed(by: self.disposeBag)
有没有办法,rx
样式?
答案 0 :(得分:3)
这样的东西?
let callApiTrigger = BehaviorRelay<Bool>(value: true)
let callApiEnoughTimes = callApiTrigger.asObservable()
.takeWhile { $0 }
.flatMap { _ in
return getData(someId)
}
.do(onNext: { (apiResult: Bool) in
callApiTrigger.accept(apiResult)
})
答案 1 :(得分:0)
takeWhile
和take(X)
不起作用的原因是因为他们没有重新订阅Observable。网络请求可观察通常最多发出一个值。
您正在寻找的东西需要某种形式的递归/重新订阅。如果您想要硬核Rx我建议您对retry
运算符进行反向工程以满足您的需求。虽然我认为自己对RxSwift很有经验,但这似乎是一个过头的桥梁。
幸运的是,我掀起了一种也很好的递归方法:)
class PageService {
typealias Page = (pageNumber: Int, items: [String]?)
private func getPage(_ pageNumber: Int) -> Observable<Page> {
let pageToReturn = Page(pageNumber: pageNumber, items: (pageNumber < 3) ? ["bert, henk"] : nil)
return Observable<Page>
.just(pageToReturn)
.delay(0.5, scheduler: MainScheduler.instance)
}
func allPagesFollowing(pageNumber: Int) -> Observable<Page> {
let objectToReturnInCaseOfError = Page(pageNumber: pageNumber + 1, items: nil)
return getPage(pageNumber + 1)
// in order to error out gracefully, you could catch the network error and interpret it as 0 results
.catchErrorJustReturn(objectToReturnInCaseOfError)
.flatMap { page -> Observable<Page> in
// if this page has no items, do not continue the recursion
guard page.items != nil else { return .empty() }
// glue this single page together with all the following pages
return Observable<Page>.just(page)
.concat(self.allPagesFollowing(pageNumber: page.pageNumber))
}
}
}
_ = PageService().allPagesFollowing(pageNumber: 0)
.debug("get page")
.subscribe()
这将打印:
2018-03-30 11:56:24.707: get page -> subscribed
2018-03-30 11:56:25.215: get page -> Event next((pageNumber: 1, data: Optional(["bert, henk"])))
2018-03-30 11:56:25.718: get page -> Event next((pageNumber: 2, data: Optional(["bert, henk"])))
2018-03-30 11:56:26.223: get page -> Event completed
2018-03-30 11:56:26.223: get page -> isDisposed