如何使用RXSwift Flat Map串联Google Places查询与自有API校验请求
RxSwift 用flatMap串联两步异步请求实现方案
首先需要把现有回调形式的API封装为Rx可观察序列,才能使用flatMap操作符串联请求,完整实现逻辑如下:
1. 封装Google Places查询接口为Observable
import RxSwift import RxCocoa extension Reactive where Base: GMSPlacesClient { func lookUpPlaceID(_ placeID: String) -> Observable<GMSPlace> { return Observable.create { observer in base.lookUpPlaceID(placeID) { place, error in if let error = error { observer.onError(error) return } guard let place = place else { observer.onError(NSError(domain: "GMSPlacesError", code: -1, userInfo: [NSLocalizedDescriptionKey: "未获取到有效地点信息"])) return } observer.onNext(place) observer.onCompleted() } return Disposables.create() } } }
2. 封装自有服务校验接口为Observable
你原有checkPlace方法实际是异步GET请求,调整为返回Observable类型:
func checkPlace(place: GMSPlace) -> Observable<Bool> { return Observable.create { observer in // 替换为你实际的GET请求逻辑 let coordinate = place.coordinate let apiUrl = URL(string: "你的自有服务校验接口地址?lat=\(coordinate.latitude)&lng=\(coordinate.longitude)")! let task = URLSession.shared.dataTask(with: apiUrl) { data, response, error in if let error = error { observer.onError(error) return } // 解析接口返回值判断是否在运营范围,示例写死返回值 let isValid = true observer.onNext(isValid) observer.onCompleted() } task.resume() return Disposables.create { task.cancel() } } }
3. 用flatMap串联请求,替换选中行逻辑
flatMap作用是接收上一步请求返回的地点对象,作为参数传入第二步校验请求,自动把两个异步流串接起来,避免嵌套回调:
// 类内部声明DisposeBag管理订阅生命周期 private let disposeBag = DisposeBag() func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) { progress.startAnimating() let targetPlaceID = placesArray[indexPath.row].placeID // 第一步发起Google Places查询 GMSPlacesClient.shared().rx.lookUpPlaceID(targetPlaceID) // flatMap串联第二步校验请求 .flatMap { [weak self] place -> Observable<Bool> in guard let self = self else { return .empty() } return self.checkPlace(place: place) } // 切换到主线程处理UI .observe(on: MainScheduler.instance) .subscribe( onNext: { [weak self] isValid in guard let self = self else { return } if isValid { // 运营范围内的业务逻辑 } else { // 超出运营范围的提示逻辑 } }, onError: { [weak self] error in guard let self = self else { return } // 统一处理两步请求的所有错误 print("请求失败: \(error.localizedDescription)") self.progress.stopAnimating() }, onCompleted: { [weak self] in guard let self = self else { return } self.progress.stopAnimating() } ) .disposed(by: disposeBag) }
注意事项
- 两步请求任意一步出错都会直接走到
onError回调,不需要每层单独做错误判断 - 所有UI更新操作必须切换到主线程执行,因此加上
observe(on: MainScheduler.instance) - 所有闭包加
[weak self]避免循环引用导致内存泄漏
内容的提问来源于stack exchange,提问作者Mohammed Riyadh
相关产品推荐
相关产品推荐

