如何在函数中抛出一个闭包?

问题描述 投票:2回答:1

我正在重构我的代码以使一切更清洁。我向我的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 - >()'到非投掷函数类型的转换无效(数据?,URLResponse?,错误?) - > Void'

我明白这是因为我试图抛出dataTask函数,但我的问题是,有什么方法可以实现这一点吗?

swift closures throw
1个回答
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)
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.