RxSwift:如何根据Observable<Bool>条件返回Observable<String>
RxSwift 组合Observable判断返回对应字符串流的实现
核心注意点:你无法用同步if直接判断Observable<Bool>类型的返回值,Observable是异步事件流,所有逻辑需要在流的操作链中完成。
现有校验方法
你已经实现的两个校验方法如下:
func isValidPassword(_ str: PublishSubject<String>) -> Observable<Bool> { return str.asObservable().map { validator.isValidPasswordRegex($0) && $0.count >= 8 } } func isNotEmpty(_ str: PublishSubject<String>) -> Observable<Bool> { return str.asObservable().map { $0.count != 0 } }
正确实现方式
方式1:直接在输入流的转换中做判断(性能最优)
不需要额外组合多个流,直接监听输入字符串的变化,按你定义的优先级顺序做判断返回对应提示即可:
func someFunc(_ str: PublishSubject<String>) -> Observable<String> { str.asObservable() .map { input in // 优先判断密码合法性 let isValidPwd = validator.isValidPasswordRegex(input) && input.count >= 8 guard isValidPwd else { return "Not a valid password" } // 密码合法后判断非空 if input.count != 0 { return "String is not empty" } // 逻辑兜底,实际密码合法时必然非空,可根据业务调整默认值 return "" } }
方式2:复用已有校验方法,通过combineLatest组合流
如果你需要保留独立的两个校验方法、不想重复写校验逻辑,可以用combineLatest把输入流、两个校验结果流组合起来,每次任意一个流发出新值就做判断:
func someFunc(_ str: PublishSubject<String>) -> Observable<String> { Observable.combineLatest( str.asObservable(), isValidPassword(str), isNotEmpty(str) ) .map { _, pwdValid, notEmpty in if !pwdValid { return "Not a valid password" } if notEmpty { return "String is not empty" } return "" } }
注意事项
- 判断优先级严格按照你写的顺序执行:密码不合法的提示优先级最高,只有密码完全符合规则时才会返回非空提示
- 现有逻辑存在冗余:密码合法的前提就是长度≥8,必然非空,第二个判断永远成立,你可以根据实际业务需求调整判断顺序和提示文案
- 如果需要做阻断式的错误处理,可以替换
map为flatMap,不符合条件时返回Observable.error(自定义错误),符合条件时返回Observable.just(对应提示)即可
内容的提问来源于stack exchange,提问作者forestvine
相关产品推荐
相关产品推荐

