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
相关产品推荐
相关产品推荐

