RxSwift链接请求

时间:2019-01-21 08:48:38

标签: swift networking observable rx-swift chaining

我面临的问题是链接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 个答案:

答案 0 :(得分:0)

Mukesh是正确的,您应该避免使用Driver直到最后。另外,当您只关心最后一种(RequestState)时,同时拥有两种RequestState<User>类型毫无意义

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

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<String>

它还假设fbLogin()userLogin(request:)各自仅发出一个值。您可能需要考虑将它们切换到Single