【问题标题】:call func in Asynchronous requests chaining RxSwift and Alamofire在链接 RxSwift 和 Alamofire 的异步请求中调用 func
【发布时间】:2020-01-29 03:11:04
【问题描述】:

我是 RxSwift 的初学者,这是我的问题,我的应用程序必须执行 3 个请求,其中 3 个是 gets,我的工作团队建议我使用 flatmap 连续执行三个请求,但我不知道应该如何使用 flatmap。

这是我的要求

public func login(param: [String:String]) -> Observable<messageModel>{
        return Observable.create { observer -> Disposable in
            self.alamoFireManager!.request(self.urlServer!+endPoints.login.login, method: .post, parameters: param, encoding: URLEncoding.default, headers: nil, interceptor: nil).responseDecodable { (res: DataResponse<messageModel,AFError>) in
                if let error = res.error {
                    observer.onError(error)
                } else if let valueEntitie = res.value {
                    observer.onNext(valueEntitie)
                }
                observer.onCompleted()
            }
            return Disposables.create()
        }
    }


public func me()  -> Observable<meModel>{
        return Observable.create { observer -> Disposable in
            self.alamoFireManager!.request(self.urlServer!+endPoints.login.me, method: .get, parameters: nil, encoding: URLEncoding.default, headers: nil, interceptor: nil).responseDecodable { (res: DataResponse<meModel,AFError>) in
                if let error = res.error {
                    observer.onError(error)
                } else if let valueEntitie = res.value {
                    observer.onNext(valueEntitie)
                }
                observer.onCompleted()
            }
            return Disposables.create()
        }
    }


public func entitie(entityId: String) -> Observable<entitieModel>{
        return Observable.create { observer -> Disposable in
            self.alamoFireManager!.request(self.urlServer!+endPoints.login.entities+"/"+entityId, method: .get, parameters: nil, encoding: URLEncoding.default, headers: nil, interceptor: nil).responseDecodable { (res: DataResponse<entitieModel,AFError>) in
                if let error = res.error {
                    observer.onError(error)
                } else if let valueEntitie = res.value {
                    observer.onNext(valueEntitie)
                }
                observer.onCompleted()
            }
            return Disposables.create()
        }
    }

第一个端点是login及其参数,然后me,函数me响应一个id,这个id是第三个请求所必需的,即entitie

我正在用这种方式制作平面地图。

networkManagerShareCore.share.login(param: param)
                .flatMap { resMessageModel in
                    //saveData(resMessageModel)
                    networkManagerShareCore.share.me()
                        .flatMap { resMeModel in
                         //saveData(resMessageModel)
                         networkManagerShareCore.share.entitie(entityId: "\(resModelMe.data.personId!)")
                    }
            }.subscribe(onNext: { (model) in
                print(model)
            }, onError: { (error) in
                self.errorMsg.accept(error.localizedDescription)
                self.isSuccess.accept(false)
            }, onCompleted: nil) {
                print("Disposed")
            }

代码有效,但在//saveData(resMessageModel) 行中我不能将其称为函数,我想保存模型,但如果我尝试调用函数,Xcode 会显示此错误:Unable to infer complex closure return type; add explicit type to disambiguate 那么,我该如何解决呢?

【问题讨论】:

标签: swift alamofire rx-swift


【解决方案1】:

RxSwift flatMap 期望某个 Observable 的返回值。

FlatMap 运算符通过应用函数来转换 Observable 您为源 Observable 发出的每个项目指定的,其中 该函数返回一个 Observable,它本身会发出项目。

您需要在每个 flatMap 调用中添加一个 return 语句。此外,您需要显式定义闭包的返回类型。

所以最里面的 flatMap 调用应该是这样的:

 networkManagerShareCore.share.me()
       .flatMap { resMeModel -> Observable<entitieModel> in
             //saveData(resMessageModel)
             return networkManagerShareCore.share.entitie(entityId: "\(resModelMe.data.personId!)")

您通常不会在 flatMap 中嵌入 flatMap,而只需按顺序组合它们以使代码更清晰。并且不要忘记已处置(by:)。最终结果如下所示:

networkManagerShareCore.share.login(param: param)
    .flatMap { resMessageModel -> Observable<meModel> in
          //saveData(resMessageModel)
          return networkManagerShareCore.share.me()
     }
     .flatMap { resMeModel -> Observable<entitieModel> in
           //saveData(resMessageModel)
           return networkManagerShareCore.share.entitie(entityId: "\(resModelMe.data.personId!)")
     }
     .subscribe(
         onNext: { (model) in
                  print(model)
         }, 
         onError: { (error) in
            self.errorMsg.accept(error.localizedDescription)
            self.isSuccess.accept(false)
         }, 
         onCompleted: nil) {
            print("Disposed")
     }
     .disposed(by: disposeBag)

【讨论】:

  • 感谢 Dale,您的回答帮助我理解了 flatmap 函数
【解决方案2】:

戴尔的回答有效,但我倾向于将保存转移到 do 运算符中。像这样:

networkManagerShareCore.share.login(param: param)
    .do(onNext: { [weak self] resMessageModel in
        self?.saveData(resMessageModel)
    })
    .flatMap { _ in
        networkManagerShareCore.share.me()
    }
    .do(onNext: { [weak self] resMeModel in
        self?.saveData(resMeModel)
    })
    .flatMap { resMeModel in
        networkManagerShareCore.share.entitie(entityId: "\(resMeModel.data.personId!)")
    }
    .subscribe(
        onNext: { (model) in
            print(model)
        },
        onError: { (error) in
            self.errorMsg.accept(error.localizedDescription)
            self.isSuccess.accept(false)
        },
        onCompleted: nil,
        onDisposed: {
            print("Disposed")
        }
    )
    .disposed(by: disposeBag)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-07-05
    • 2016-08-19
    • 2019-07-18
    • 2016-06-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-04-22
    相关资源
    最近更新 更多