我正在尝试使用 alamofire 和 rxswift 来使用 api。我已经编写了方法,但观察者的 onNext 只被调用一次。我正在尝试通过递归调用来做到这一点。这有什么问题吗? Api 将根据时间戳一次返回 10 个对象。所以我检查刚刚返回的数组是否包含 10 个对象。如果是,那么还有更多,如果不是,那就结束了。
func fetchPersonalization(fromList:[Personalization],timeStamp:Int) -> Observable<PersonalizationContainer>
{
let dictHeader = ["Accept":"application/json","regid" : pushtoken , "os" : "ios" , "token" : token , "App-Version" : "1324" , "Content-Type" : "application/json"]
return fetchPersonalizationUtil(dictHeader: dictHeader, timeStamp: timeStamp)
.flatMap { (perList) -> Observable<PersonalizationContainer> in
let persoList:[Personalization] = perList.list
let finalList = fromList + persoList
if(persoList.count==10){
let newTimeStamp = persoList.last!.lastModifiedAt! - 1
return Observable.merge(Observable.just(PersonalizationContainer(l: finalList, d: perList.data)),
self.fetchPersonalization(fromList:finalList,timeStamp: newTimeStamp)
)
//self.fetchPersonalization(fromList:finalList,timeStamp: newTimeStamp)
}else {
return Observable.just(PersonalizationContainer(l: finalList, d: Data()))
}
}
}
func fetchPersonalizationUtil(dictHeader:[String:String],timeStamp:Int) -> Observable<PersonalizationContainer>
{
return Observable<PersonalizationContainer>.create({ (observer) -> Disposable in
Alamofire.request("https://mranuran.com/api/hubs/personalization/laterthan/\(timeStamp)/limit/10/" ,headers: dictHeader).responseData { response in
if let json = response.result.value {
//print("HUBs JSON: \(json)")
do {
let list = try JSONDecoder().decode([Personalization].self, from: json)
let pContainer = PersonalizationContainer(l: list, d: json)
print("ANURAN \(list[0].name)")
observer.onNext(pContainer)
observer.onCompleted()
}catch {
print(error)
observer.onError(error)
}
}
else{
observer.onError(response.result.error!)
}
}
return Disposables.create()
})
}
我在 onNext 方法上放置了一个断点,它似乎只被调用一次。在他们的官方 github 存储库中被这个问题和 RxSwift 的 GithubRepo 示例困扰了几个小时,我无法弄清楚他们在做什么。我的流程可能出了什么问题?
最佳答案
我不久前使用 Promises 写了这篇文章,这里使用的是 Singles。
您传入:
- 用于进行第一次网络调用的种子。
- pred 将获得最近一次调用的结果,并生成一个参数以进行下一个网络调用,如果完成则生成 nil。 (如果需要再次调用,您可以在此处检查计数并返回下一个时间戳。)
- 进行网络调用的生产者。
它最终返回一个包含所有结果的数组的 Single。任何内网调用出错都会报错。
func accumulateWhile<T, U>(seed: U, pred: @escaping (T) -> U?, producer: @escaping (U) -> Single<T>) -> Single<[T]> {
return Single.create { observer in
var disposable = CompositeDisposable()
var accumulator: [T] = []
let lock = NSRecursiveLock()
func loop(_ u: U) {
let product = producer(u)
let subDisposable = product.subscribe { event in
lock.lock(); defer { lock.unlock() }
switch event {
case let .success(value):
accumulator += [value]
if let u = pred(value) {
loop(u)
}
else {
observer(.success(accumulator))
}
case let .error(error):
observer(.error(error))
}
}
_ = disposable.insert(subDisposable)
}
loop(seed)
return disposable
}
}
我不认为锁实际上是必要的,但我把它放在以防万一。
关于swift - 如何使用 RxSwift 和 Alamofire 进行分页?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52115380/