作者:Olivier Halligon,原文链接,原文日期:2016-02-06
译者:ray16897188;校对:小锅;定稿:numbbbbb
在之前的一篇文章中,我介绍了如何在Swift中使用throw
做错误处理。但是如果你处理的是异步流程,throw
就无法胜任,该怎么办?
throw
和异步有啥问题?
回顾下,我们可以像下面这样,在一个可能失败的函数中使用 throw
关键字:
// 定义错误类型和一个可抛出的函数 enum computationError: ErrorType { case DivisionByZero } func inverse(x: Float) throws -> Float { guard x != 0 else { throw computationError.DivisionByZero } return 1.0/x } // 调用它 do { let y = try inverse(5.0) } catch { print("Woops: \(error)") }
但如果函数是异步的,需要等待一段时间才会返回结果,比如带着 completion block 的函数,这个时候怎么办?
func fetchUser(completion: User? /* throws */ -> Void) /* throws */ { let url = … NSURLSession.sharedSession().dataTaskWithURL(url) { (data,response,error) -> Void in // if let error = error { throw error } // 我们不能这样做,fetchUser 不能“异步地抛出” let user = data.map { User(fromData: $0) } completion(user) }.resume() } // 调用 fetchUser() { (user: User?) in /* do something */ }
这种情况下如果请求失败的话,你怎么 throw
?
让
fetchUser
函数throw
是不合理的,因为这个函数(被调用后)会立即返回,而网络错误只会在这之后发生。所以当错误发生时再throw
一个错误就太晚了,fetchUser
函数调用已经返回。你可能想把
completion
标成throws
?但是调用completion(user)
的代码在fetchUser
里,不是在调用fetchUser
的代码里。所以接受并处理错误的代码必须是fetchUser
本身,而非fetchUser
的调用点。所以这个方案也不行。版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 [email protected] 举报,一经查实,本站将立刻删除。