使用RxSwift实现设备数组依次连接:成功即终止,失败重试下一个
问题分析
你当前的代码存在两个核心问题:
- 使用
flatMap会并发执行所有设备的连接操作,不符合「依次尝试」的需求; flatMap会合并所有Completable,只有当全部操作完成时才触发onCompleted,导致连接成功后仍会继续尝试后续设备。
解决方案
下面的代码实现了「依次尝试连接,成功即终止,失败则继续,全部失败则抛出错误」的逻辑:
Observable.from(devices) .enumerated() .concatMap { index, device -> Observable<Void> in // 将连接操作转为Observable,成功时发出信号,失败则根据索引处理 service.connectTo(device: device) .asObservable() .catch { error -> Observable<Void> in // 最后一个设备连接失败时抛出错误,否则返回empty继续尝试下一个 if index == devices.count - 1 { return Observable.error(error) } else { return Observable.empty() } } } .take(1) // 捕获第一个连接成功的信号,立即终止后续操作 .ignoreElements() // 将Observable转为Completable,适配回调需求 .subscribe( onError: { error in // 所有设备连接失败时的错误处理 }, onCompleted: { // 任意一个设备连接成功时触发 } ) .disposed(by: bag)
代码说明
concatMap:保证设备连接操作按顺序依次执行,前一个操作完成(无论成功或转为empty)后才会启动下一个;- 错误捕获逻辑:连接失败时,若不是最后一个设备,返回
Observable.empty()让序列继续执行;若是最后一个设备,直接抛出错误表示全部尝试失败; take(1):一旦捕获到第一个连接成功的信号,立即终止后续所有设备的尝试,完全符合「成功即停止」的需求;ignoreElements():将发出单个元素的Observable转为Completable,匹配你需要的onCompleted/onError回调形式。
内容的提问来源于stack exchange,提问作者eXceLLenT
相关产品推荐
相关产品推荐

