RxSwift 链接请求

Posted

技术标签:

【中文标题】RxSwift 链接请求【英文标题】:RxSwift Chaining requests 【发布时间】:2019-01-21 08:48:37 【问题描述】:

我面临的问题是链接 2 个请求并处理错误。 下面是我的代码示例:

func fbLogin() -> Observable<String>  ... 

func userLogin(request: Request) -> Observable<User>  ... 

let signedWithLogin = loginTaps
    .asDriver(onErrorJustReturn: ())
    .flatMapLatest  _ in
        return fbLogin()
        .map( ReqestState<String>.loaded($0) )
        .asDriver(onErrorRecover:  error  in
            return Driver.just(.error(error))
        )
        .startWith(.loading)
     
     .map( UserEndpoint.socialLogin(token: $0) )
     .flatMapLatest  request in
         return userLogin(request: request)
         .map( ReqestState<User>.loaded($0) )
         .asDriver(onErrorRecover:  error  in
              return Driver.just(.error(error))
         )
         .startWith(.loading)
     

signedWithLogin
    .drive(onNext:  response in
        print(response)
     )
    .disposed(by: disposeBag)

问题是当我取消 Facebook 登录弹出窗口时,我发送 observer.onError(FBLoginManagerError.canceled) 错误。此错误首先捕获 .asDriver(onErrorRecover: error 方法,但不会传递给 .drive(onNext: response 方法。

如何捕获.asDriver(onErrorRecover: error 方法中的所有错误?

【问题讨论】:

【参考方案1】:

Mukesh 是正确的,你应该避免Driver 直到最后。此外,当您只真正关心最后一种 (RequestState&lt;User&gt;) 时,同时拥有两种 RequestState 类型并没有什么意义

这是一个更简单的版本,我认为它可以满足您的需求:

let signedWithLogin = loginTaps
    .flatMapLatest 
        fbLogin()
            .map  UserEndpoint.socialLogin(token: $0) 
            .flatMap  userLogin(request: $0) 
            .map  RequestState.loaded($0) 
            .catchError  .just(.error($0)) 
            .startWith(.loading)
    
    .asDriver(onErrorRecover:  fatalError($0.localizedDescription) ) // I'm using `fatalError()` here because if the above emits an error something has gone horribly wrong (like the RxSwift library isn't working anymore.)

signedWithLogin
    .drive(onNext:  response in
        print(response)
    )
    .disposed(by: disposeBag)

以上假设您将UserEndpoint.socialLogin(token:) 函数更改为接受字符串而不是RequestState&lt;String&gt;

它还假设fbLogin()userLogin(request:) 每个只发出一个值。您可能需要考虑将它们切换为 Singles。

【讨论】:

这个解决方案真的很有用。谢谢!

以上是关于RxSwift 链接请求的主要内容,如果未能解决你的问题,请参考以下文章

RxSwift,分享+重试机制

RxSwift 更新身份验证令牌

RxSwift 观察模型的变化并提出请求

RxSwift:链接流的问题

RxSwift 取消 RxMoya 网络请求

RxSwift - 递归 Observables?