You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

RxSwift中如何链式调用login与getUser请求实现全链路同步完成

问题核心

现有代码的问题是getUser()是独立于登录请求的Rx序列之外的异步逻辑,do(onSuccess:)不会等待内部异步任务完成,就会直接执行后续的asVoid返回结果,导致用户信息还没处理完就已经触发了跳转逻辑。


改造方案

第一步 调整getUser方法返回值

把原来无返回值的getUser改成返回Single<Void>,将用户请求、存储逻辑整合成完整的可串联序列:

private func getUser() -> Single<Void> {
    return request(type: UserNew.self, endpoint: ApiUserRouter.me)
        .do(onSuccess: { [unowned self] user in
            // 同步存储用户信息到数据库和全局管理类
            try self.realmManager.writeSync({ realm in
                realm.add(user, update: .modified)
            })
            self.apiService.authenticationManager.setUser(user: user)
        })
        .asVoid()
}

第二步 用flatMap串联全流程

修改login方法,使用flatMap操作符将令牌存储后的逻辑切换到用户信息请求流,只有当用户信息处理完成后,整个序列才会结束:

func login(email: String, password: String) -> Single<Void> {
    return request(type: Auth.self, endpoint: ApiAuthRouter.login(email: email, password: password))
        // 第一步:登录成功后存储令牌
        .do(onSuccess: { [unowned self] auth in
            self.apiService.authenticationManager.setAuthTokens(auth: auth)
        })
        // 第二步:令牌存储完成后,串联用户信息请求流
        .flatMap { [unowned self] _ in
            self.getUser()
        }
}

外部调用示例

在订阅login方法的成功回调后再执行首页跳转,就能保证所有逻辑都执行完成:

login(email: "用户输入的邮箱", password: "用户输入的密码")
    .subscribe(onSuccess: { _ in
        // 登录、存令牌、拉取用户信息、存用户信息全流程完成,跳转首页
        Router.navigateToHome()
    }, onError: { error in
        // 统一处理全流程任意环节的错误,比如登录失败、用户信息拉取失败
        Toast.showError(message: error.localizedDescription)
    })
    .disposed(by: disposeBag)

方案优势

  • 所有流程严格按顺序执行,前一步失败就会终止后续逻辑,不会出现状态不一致的问题
  • 全链路错误可以在同一个订阅里统一处理,不需要分散管理多个异步流的异常
  • 完全依赖Rx原生操作符保证时序,没有额外的状态标记逻辑,代码可读性和可维护性更高

内容的提问来源于stack exchange,提问作者Dick Thunder

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.07 02:45:01