微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

如何处理 Swift 中的异步错误

作者: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] 举报,一经查实,本站将立刻删除。

相关推荐