使用RxSwift同步异步网络调用

时间:2017-07-31 06:15:28

标签: ios swift asynchronous rx-swift

我正在使用Facebook来验证用户身份。此过程发生异步。完成此操作后,我必须通过firebase对用户进行身份验证,这会发生异步。即使我使用的是RxSwift,我最终也会嵌套异步任务,就像我使用回调并最终回调地狱一样。

我目前的程序似乎并不合适。有点难读。是我还是有更优雅的方法来处理多个异步网络呼叫。

对于这个例子,我拿出了错误事件,因为它使代码的可读性更低。

感谢您的任何提示或指导。

func rx_login(viewController: UIViewController) {

    /// Facebook login
    rx_facebookLogin(viewController: viewController)
        .asObservable()
        .subscribe(onNext: { [weak self] (credentials: AuthCredential, userInfo: [String: Any]) in

            /// Firebase Login
            rx_firebaseLogin(with: credentials)
                .asObservable()
                .subscribe(onNext: { [weak self] (uid) in

                    /// TODO: Save user info firebase db


                }).addDisposableTo(disposeBag)

        }).addDisposableTo(disposeBag)

1 个答案:

答案 0 :(得分:2)

尝试使用flatMapLatest

/// Facebook login
rx_facebookLogin(viewController: viewController)
    .flatMapLatest { credentials, _ in rx_firebaseLogin(with: credentials) }
    .subscribe(onNext: { [weak self] (uid) in
        /// TODO: Save user info firebase db
    })
    .addDisposableTo(disposeBag)

要处理错误,您可以使用mapfilter,例如:

let facebookLogin = rx_facebookLogin(viewController: viewController)
    .map { credentials, userInfo -> (AuthCredential, String?) in
        let error = userInfo["error"] as? String
        return (credentials, error)
    }
    .shareReplayLatestWhileConnected()

// Success
facebookLogin
    .filter { _, error in error == nil }
    .flatMapLatest { credentials, _ in rx_firebaseLogin(with: credentials) }
    .subscribe(onNext: { (uid) in
        // Success!
    })
    .addDisposableTo(disposeBag)

// Fail
facebookLogin
    .filter { _, error in error != nil }
    .subscribe(onNext: { _, error in
        // Error!
        print(error)
    })
    .addDisposableTo(disposeBag)