下面的函数做了三件事......
时区获取和天气获取都是需要一些时间的请求……我希望它们同时运行。我还想确信,一旦到达时区和天气数据,我就可以安全地对其进行操作。
这段代码能做到吗?如何改进以提高可读性?
func getWeather() async {
do {
async let grabWeather = WeatherService.shared.weather(for: self.location)
async let grabPlacemarks = CLGeocoder().reverseGeocodeLocation(self.location)
weather = try await grabWeather
guard let grabTimezone = try await grabPlacemarks.first?.timeZone else {
print("Error – no timezone")
return
}
timezone = grabTimezone
// Do something with timezone and weather below
// ...
} catch {
fatalError("\(error)")
}
}
你问:
这段代码是否完成了[并发执行]?
是的。这是
async let
的全部目的。见SE-0317或并行调用异步函数。
如何改进……?
一些观察:
如果其中一项服务失败,一个人不想使用
fatalError
使应用程序崩溃。我们应该抛出错误并让调用者使用本地化的错误消息更新其 UI。
“抓取”变量名不遵循标准约定,可以简化代码以使其变得不必要。
这会产生更简单的东西,例如:
func getWeather() async throws {
async let placemarks = CLGeocoder().reverseGeocodeLocation(location)
let weather = try await WeatherService.shared.weather(for: location)
guard let timeZone = try await placemarks.first?.timeZone else {
throw WeatherError.noTimeZone
}
// Do something with timezone and weather below ...
}
不用说,它仍然同时运行这些。
地点:
enum WeatherError: Error {
case noTimeZone
}
extension WeatherError: LocalizedError {
var errorDescription: String {
switch self {
case .noTimeZone: return NSLocalizedString("Unable to identify timezone of the desired location.", comment: "WeatherError")
}
}
}