如何使用 Moya RxSwift 合并 REST 数组
Posted
技术标签:
【中文标题】如何使用 Moya RxSwift 合并 REST 数组【英文标题】:how to use Moya RxSwift to get an array of REST merged 【发布时间】:2019-05-31 19:11:16 【问题描述】:我正在尝试学习 RxSwift。我一直在使用 Moya,现在想试试 RxSwift。完全糊涂了。
let popServiceProvider = MoyaProvider<PopRESTService>()
let o1 = popServiceProvider.rx.request(.getPopByCity(city: "London")).asObservable()
let o2 = popServiceProvider.rx.request(.getPopByCity(city: "Tokyo")).asObservable()
let pObservables:[Observable<Response>] = [o1, o2]
let stats: Observable<Response> = Observable.combineLatest(pObservables)
let m = stats.map( a in
print(a)
)
首先我在 let stats 上得到一个错误:
无法将'Observable'类型的值转换为指定类型'Observable'
我是否朝着正确的方向前进?
编辑:
即使这样也行不通。永远不要先订阅:
wServiceProvider.rx.request(.getWeatherByCity(city: "Chicago"))
.debug()
.map(Weather.self)
.subscribe( (event) in
switch event
case let .success(response):
print(response)
case let .error(response):
print(response)
)
.disposed(by: self.disposeBag)
【问题讨论】:
【参考方案1】:我建议使用combineLatest
的Observable.combineLatest(o1, o2)
变体(这种形式受8 个参数的限制)
假设从 case getPopByCity(city: String)
返回的类型可能如下所示:
struct PopByCity: Decodable
let count: Float
您可能希望这样实现请求:
Observable.combineLatest(o1, o2)
.map (resp1: Response, resp2: Response) -> [PopByCity] in
let pop1 = try? JSONDecoder().decode(PopByCity.self, from: resp1.data)
let pop2 = try? JSONDecoder().decode(PopByCity.self, from: resp2.data)
return [pop1, pop2].compactMap $0
.subscribe(onNext: (result: [PopByCity]) in
print(result)
)
.disposed(by: disposeBag)
但是如果你还需要一个请求数组:
Observable.combineLatest([o1, o2])
.map (responses: [Response]) -> [PopByCity] in
responses.map try? JSONDecoder().decode(PopByCity.self, from: $0.data)
.compactMap $0
.subscribe(onNext: (result: [PopByCity]) in
print(result)
)
.disposed(by: disposeBag)
对于第二个选项,请记住,同时发送大量异步请求不是一个好习惯。对于需要执行的许多请求,如果您必须在最后一个响应之后在一个地方处理所有响应,我建议使用 Concat 运算符或 Concat + Reduce 的组合。
【讨论】:
我尝试了您的代码并在其他尝试中遇到了同样的问题:添加 debug() 告诉我“已订阅”,但在 .subscribe 中没有运行任何内容。 嗯,我不确定我是否正确,也许执行请求存在一些问题。如果我将o1
和o2
更改为模拟Single
API 调用的Observable
,例如swift let o1 = Single<PopByCity?> .just(PopByCity(count: 5000)) .delay(1, scheduler: MainScheduler.instance) .asObservable() .debug("o1")
,您可以分享的任何代码都将有助于澄清问题。我不知道你的模型结构是什么样的,或者你如何将Response
映射到模型。【参考方案2】:
我对 Apple XCTest 的误解。我需要补充:
expectation.fulfill()
在我的订阅中。
Observable.combineLatest([o1, o2])
.map (responses: [Response]) -> [Weather] in
responses.map try? JSONDecoder().decode(Weather.self, from: $0.data)
.compactMap $0
.debug()
.subscribe(onNext: (result: [Weather]) in
print(result)
expectation.fulfill()
)
.disposed(by: disposeBag)
【讨论】:
以上是关于如何使用 Moya RxSwift 合并 REST 数组的主要内容,如果未能解决你的问题,请参考以下文章
RxSwift+Moya+Moya_ObjectMapper+MJRefresh,刷新失败?