gpt4 book ai didi

swift - RxSwift 以正确的顺序链接两个信号

转载 作者:行者123 更新时间:2023-11-28 15:21:08 24 4
gpt4 key购买 nike

所以基本上我需要执行两个操作:

  • 首先是登录
  • 其次是获取用户资料

它们必须按正确的顺序完成,因为如果不先登录就无法获取用户配置文件。

所以我有一堆看起来像这样的代码:

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()
}

我知道这是不对的,因为当两个操作都完成时,我无法发送带有登录结果的 onNext 信号。我一直在阅读,我发现我需要平面化这两个 Action ,将它们组合成一个信号然后操纵 signinresult 但我不知道如何做到这一点。所以任何帮助都会很好。

谢谢

编辑 1:

所以我重构了代码看起来像这样,但仍然存在问题,当两个 Action 都完成时我无法发送信号,或者我错了吗?

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 或任何其他运算符混合使用。

我就是这样做的。希望对你有帮助

关于swift - RxSwift 以正确的顺序链接两个信号,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45977037/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com