rxswift按正确顺序链接两个信号



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

  • 首先是登录
  • 第二是获取用户个人资料

它们必须按正确的顺序完成,因为在不首先登录的情况下无法完成用户配置文件。

所以我有很多看起来像这样的代码:

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或任何其他操作员混合。

这就是我的做法。希望它会有所帮助

最新更新