【问题标题】:how to use Moya RxSwift to get an array of REST merged如何使用 Moya RxSwift 合并 REST 数组
【发布时间】:2023-03-09 18:45:01
【问题描述】:

我正在尝试学习 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)

【问题讨论】:

    标签: swift rx-swift moya


    【解决方案1】:

    我建议使用combineLatestObservable.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 中没有运行任何内容。
    • 嗯,我不确定我是否正确,也许执行请求存在一些问题。如果我将o1o2 更改为模拟Single API 调用的Observable,例如swift let o1 = Single&lt;PopByCity?&gt; .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)
    

    【讨论】:

      猜你喜欢
      • 2017-04-27
      • 2017-01-12
      • 2019-03-18
      • 1970-01-01
      • 2018-04-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-03-14
      相关资源
      最近更新 更多