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

Swift中Async/Await解惑:这段代码能否并发执行两个网络请求?

代码是否实现需求?

是的,这段代码已经实现了时区和天气请求的并发执行,同时满足“数据返回后安全操作”的要求:

  • async let声明的两个异步任务会在定义时立即启动,而非等到await时才执行,因此两个耗时请求是并行处理的。
  • 通过try await等待结果返回后再执行后续逻辑,确保了数据就绪后才进行操作。

不过代码在可读性、健壮性上还有优化空间,下面是具体优化方案:

优化方案(提升可读性与健壮性)

1. 合并异步等待,明确并发语义

将分别等待两个任务的逻辑改为同时等待,更直观体现“并发执行后统一处理结果”的设计意图:

func getWeather() async {
    do {
        async let weatherResponse = WeatherService.shared.weather(for: location)
        async let placemarks = CLGeocoder().reverseGeocodeLocation(location)
        
        // 同时等待两个并发任务完成
        let (weatherResult, placemarksResult) = try await (weatherResponse, placemarks)
        
        // 处理天气数据
        self.weather = weatherResult
        
        // 提取时区信息
        guard let timezone = placemarksResult.first?.timeZone else {
            print("无法获取时区信息")
            return
        }
        self.timezone = timezone
        
        // 统一处理时区与天气数据
        processWeatherAndTimezone(weather: weatherResult, timezone: timezone)
        
    } catch {
        // 替换致命错误为合理的错误处理(如通知UI层展示错误)
        print("请求失败:\(error.localizedDescription)")
    }
}

// 抽离数据处理逻辑,让主函数职责更单一
private func processWeatherAndTimezone(weather: Weather, timezone: TimeZone) {
    // 此处编写时区与天气的业务处理逻辑
}

2. 优化命名与代码拆分

  • 给异步任务结果起清晰的名称(如weatherResponse、placemarksResult),避免模糊的grabXX前缀。
  • 将“时区与天气数据处理”逻辑抽离为单独函数,降低主函数复杂度,提升代码模块化程度。

3. 保障线程安全(针对UI场景)

如果weather和timezone是用于UI展示的属性,需确保在主线程更新(异步任务可能在后台线程执行),可以用@MainActor或主线程队列包裹赋值操作:

// 示例:在主线程更新UI属性
Task { @MainActor in
    self.weather = weatherResult
    self.timezone = timezone
}

4. 改进错误处理

原代码的fatalError会直接导致应用崩溃,生产环境中应替换为更温和的处理方式,比如打印错误日志、向用户展示提示弹窗,或通过回调/返回值向上传递错误。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.23 12:57:52