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

如何使用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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.05 20:54:02