所以我基本上有两个操作需要执行:
- 首先是登录
- 第二是获取用户个人资料
它们必须按正确的顺序完成,因为在不首先登录的情况下无法完成用户配置文件。
所以我有很多看起来像这样的代码:
func signIn(signinParameters: SignInParameters) -> Observable<SignInResult> {
return Observable<SignInResult>.create { [unowned self] observer in
self.signinParameters = signinParameters
self.apiConnector
.signIn(with: signinParameters)
.do(onNext: { [weak self] signinResult in
self!.apiConnector
.get()
.do(onNext: { user in
let realm = RealmManager.shared.newRealm()!
let realmUser = RealmUser()
realmUser.configure(with: user, in: realm)
try? realm.write {
realm.add(realmUser, update: true)
}
self!.setState(.authenticated)
observer.onNext(signinResult)
}, onError: { (error) in
observer.onError(error)
}, onCompleted: {
observer.onCompleted()
}).subscribe()
}, onError: { error in
observer.onError(error)
}, onCompleted: {
print("completed")
observer.onCompleted()
}).subscribe()
return Disposables.create()
}
我知道这是不正确的,因为当两个动作完成后,我无法发送带有签名结果的onext信号。我一直在阅读,我想知道我需要将这两个动作放置,然后将它们组合到一个信号中,然后操纵标志,但我不知道如何做到这一点。所以任何帮助都很好。
谢谢
编辑1:
所以我已经重新制作了这样的代码,但是当两个操作完成时,我仍然无法发送信号,或者我错了?
?func signIn(signinParameters: SignInParameters) -> Observable<SignInResult> {
return Observable<SignInResult>.create { [unowned self] observer in
self.signinParameters = signinParameters
self.apiConnector
.signIn(with: signinParameters)
.do(onNext: { (result) in
}, onError: { (error) in
}, onCompleted: {
})
.flatMap({ (result) -> Observable<User> in
self.apiConnector.get().asObservable()
})
.do(onNext: { (user) in
}, onError: { (error) in
}, onCompleted: {
}).subscribe()
return Disposables.create()
}
}
您的代码不是很干净,很难理解发生了什么(我的意见)。
如果您需要执行两个操作,则可以创建两个功能:
struct Parameters{}
struct Profile{}
struct User{}
func login(parameters: Parameters) -> Observable<User> {
// get user
}
func profile(user: User) -> Observable<Profile> {
// get profile
}
func serial(parameters: Parameters) -> Observable<Profile> {
return login(parameters: parameters).flatMap({ profile(user: $0) })
}
login
功能或profile
功能也可以根据需要分为较小的功能:
func profileStored(user: User) -> Observable<Profile?> {
// get stored profile
}
func profileRequested(user: User) -> Observable<Profile> {
// get profile from network
}
func profile(user: User) -> Observable<Profile> {
let observable = profileStored(user: user)
.shareReplayLatestWhileConnected()
let observableStored = observable
.filter({ $0 != nil })
.map({ $0! })
.shareReplayLatestWhileConnected()
let observableRequested = observable
.filter({ $0 == nil })
.flatMap({ _ in profileRequested(user: user) })
.shareReplayLatestWhileConnected()
return Observable
.of(observableStored, observableRequested)
.merge()
.shareReplayLatestWhileConnected()
}
因此,您可以将较小功能与flatMap
或任何其他操作员混合。
这就是我的做法。希望它会有所帮助