作者: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 的调用点。所以这个方案也不行。 (编辑:李大同)
【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!
|