【问题标题】:How to throw inside a closure in a function?如何在函数的闭包内抛出?
【发布时间】:2019-08-30 01:20:43
【问题描述】:

我正在重构我的代码,让一切变得更干净。我向我的 API 发出请求,并且可以期待不同类型的返回值,因此我创建了一个通用函数来简化我的代码。

我希望这个函数抛出,所以我可以简单地使用do catch 来处理不同类型的错误或成功案例。

这是我的功能:

func performRequest<T: Codable>(_ request: URLRequest, ofType: T.Type) throws -> T{
    URLSession.shared.dataTask(with: request) {(data, response, err) in
        if let err = err {throw err}
        if let response = response as? HTTPURLResponse {
            if response.statusCode != 200 {
                // Here I would return the value
            } else {
                // here I would throw the error
            }
        }
        }.resume()
}

但是在URLSession.shared.dataTask 之后的第一行我得到了这个错误:

从'(_, _, _) throws -> ()' 类型的抛出函数到非抛出函数类型'(Data?, URLResponse?, Error?) -> Void'的无效转换

我明白那是因为我试图在 dataTask 函数中抛出,但我的问题是,有没有办法做到这一点?

【问题讨论】:

  • 您不能在URLSession.shared.dataTask 的完成处理程序中使用throw,因为该完成处理程序的类型已经定义并且它不是throws 函数。

标签: swift closures throw


【解决方案1】:

您的呼叫是异步的。收到数据后,您需要在闭包内返回数据。检查调用是否成功可以使用新引入的Result类型,所以你不需要throw

func performRequest<T: Codable>(_ request: URLRequest, completion: @escaping (Result<T, Error>) -> Void) {
    URLSession.shared.dataTask(with: request) { (data, response, err) in
        if let err = err {
            return completion(Result.failure(err))
        }
        if let response = response as? HTTPURLResponse {
            if response.statusCode == 200 { // 200 is code for OK btw
                return completion(Result.success(someValueOfTypeT))
            } else {
                return completion(Result.failure(yourError))
            }
        }
    }.resume()
}

用法:(注意T的类型可以从闭包声明中推断出来)

performRequest(someRequest) { (result: Result<SomeTypeConformsToCodable, Error>) in
    switch result {
    case .success(let value):
        // work with value
    case .failure(let err):
        print(err)
    }
}

【讨论】:

  • Robert Dresler 非常感谢您的回答,我尝试过这种使用 throwing 函数的方法,因为我在另一个函数中调用了这个函数,该函数也接受了一个带有 Result 类型参数的 completionHandler,所以我想一旦我不得不将结果发送到另一个结果中,投掷会更清晰,现在我意识到这是要走的路......谢谢
猜你喜欢
  • 2018-06-24
  • 2017-12-04
  • 2018-06-10
  • 2017-09-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-10-14
  • 2020-03-08
相关资源
最近更新 更多