使用 RxMoya 在 RxSwift 上未获得 Completed 事件
Posted
技术标签:
【中文标题】使用 RxMoya 在 RxSwift 上未获得 Completed 事件【英文标题】:Not getting Completed event on RxSwift with RxMoya 【发布时间】:2017-09-26 09:01:44 【问题描述】:以下代码有效:
let provider = RxMoyaProvider<MyAPI>( stubClosure: MoyaProvider.delayedStub(3))
provider
.request(.studentSearch(query: ""))
.retry(3)
.observeOn(MainScheduler.instance)
.asObservable()
.mapJSON()
.map respJSON in
guard let studentsJsonArray = JSON(respJSON)["students"].array else
throw APIError.wrongJSONParsing
return studentsJsonArray.map
guard let students = Student.fromJSON($0) else
fatalError("Invalid Student Object")
return students
as [Student]
.subscribe(onNext:
print($0)
, onCompleted:
print($0) // This one is being called.
)
.disposed(by: rx.disposeBag)
上面的代码调用了onCompleted方法,下面的代码没有调用。
我正在尝试使用 UITableView 中的刷新触发器来刷新内容。我想在开始时加载内容,所以我在 ViewModel 的以下代码中使用startWith(())
let results: Driver<[Student]>
var refreshTrigger = PublishSubject<Void>()
results = refreshTrigger
.startWith(())
.do(onNext:
execute.value = true
)
.flatMapLatest
provider
.request(.studentSearch(query: ""))
.retry(3)
.observeOn(MainScheduler.instance)
.asObservable()
.mapJSON()
.map respJSON in
guard let studentsJsonArray = JSON(respJSON)["students"].array else
throw APIError.wrongJSONParsing
return studentsJsonArray.map
guard let students = Student.fromJSON($0) else
fatalError("Invalid Student Object")
return students
.do(onNext:
items.value = $0
execute.value = false
noResults.value = items.value.isEmpty
, onCompleted:
print($0)
)
.asDriver(onErrorJustReturn: [])
在控制器中,我在 viewdidload 中调用。
viewModel
.results
.asObservable()
.map StudentGroup(header: "Follower", items: $0)
.subscribe(onNext:
print($0)
, onCompleted:
print($0) // This is not being called.
)
.disposed(by: rx.disposeBag)
这里没有调用 onCompleted。不知道是什么原因?。请帮帮我。
【问题讨论】:
【参考方案1】:flatMapLatest 不会发送 onCompleted 事件,除非其输入(在您的情况下为 PublishSubject)完成。 Moya 请求可以发送自己的 onCompleted 事件,但是当 flatMapLatest 合并结果时这些事件会被过滤掉。 换句话说,从 PublishSubject 到数据源的长期订阅未完成,也不应该完成。 (已编辑) (否则你会在第一次加载后失去刷新功能。)
我从 RxSwift Slack 频道的 Zsolt Varadi 那里得到了帮助。
解决办法
results = refreshTrigger
.startWith(())
.do(onNext:
execute.value = true
)
.flatMapLatest
provider
.request(.studentSearch(query: ""))
.retry(3)
.observeOn(MainScheduler.instance)
.asObservable()
.mapJSON()
.map respJSON in
guard let studentsJsonArray = JSON(respJSON)["students"].array else
throw APIError.wrongJSONParsing
return studentsJsonArray.map
guard let students = Student.fromJSON($0) else
fatalError("Invalid Student Object")
return students
as [Student]
.map StudentGroup(header: "Follower", items: $0)
.toArray()
.catchErrorJustReturn([])
.do(onNext:
studentGroups.value = $0
execute.value = false
guard let isEmpty = studentGroups.value.first?.items.isEmpty else
return
noResults.value = isEmpty
)
.asDriver(onErrorJustReturn: [])
【讨论】:
以上是关于使用 RxMoya 在 RxSwift 上未获得 Completed 事件的主要内容,如果未能解决你的问题,请参考以下文章
使用 watchPosition 在 ios 设备上未获得准确的经纬度
使用 mvvm 模型的 RxMoya 请求总是在observer.onError(error) 中崩溃
如何正确过滤 RxMoya 中的SuccessfulStatusCodes