使用 RxSwift 同步异步网络调用
synchronize async network calls with RxSwift
我正在使用 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)
尝试使用 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)
要处理错误,可以使用map
和filter
,例如:
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)
我正在使用 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)
尝试使用 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)
要处理错误,可以使用map
和filter
,例如:
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)