使用通用参数创建 async/await 函数

Posted

技术标签:

【中文标题】使用通用参数创建 async/await 函数【英文标题】:Create async/await function with Generic Parameter 【发布时间】:2021-12-15 03:46:15 【问题描述】:

我正在尝试将我的工作完成处理函数转换为新的 async/await 语法,但是我在为使用通用参数 (T) 的函数找到正确的语法时遇到了问题:

我以前用过的和有效的:

typealias CurrentWeatherCompletionHandler = (CurrentWeather?, Error?) -> Void

private func weatherDownload<T: Codable>(weatherType: String, completionHandler completion:  @escaping (_ object: T?,_ error: Error?) -> ()) 
    let storage = Storage.storage()
    
    let pathReference = storage.reference(withPath: "\(weatherType)"+"-de.json")
    
    pathReference.getData(maxSize: 1 * 1024 * 1024)  data, error in
        
        if let error = error 
            print("Error beim \(weatherType) Download: \(error)")
            completion(nil, error)
         else 
            do 
                let weather = try self.decoder.decode(T.self, from: data!)
                completion(weather, nil)
             catch let error 
                completion(nil, error)
            
        
    


func getCurrentWeather(completionHandler completion: @escaping CurrentWeatherCompletionHandler) 
    weatherDownload(weatherType: Constants.currentWeatherFolder)  (weather: CurrentWeather?, error) in
        completion(weather, error)
    

我试过了,但没用:

private func weatherDownload<T: Codable>(weatherType: String) async -> (weather: T?, error: Error?) 
   //same network code as before but with return instead of completion:
   return (weather, nil) // Compiler Error: 'nil' requires a contextual type / Unexpected non-void return value in void function


func getCurrentWeather() async -> (weather: CurrentWeather?, error: Error?) 
    return await weatherDownload(weatherType: Constans.currentWeatherFolder)

欢迎提出任何想法。

【问题讨论】:

请在异步函数中附上您的网络逻辑的完整代码。 我的猜测是您没有将“与以前相同的网络代码”转换为异步。 感谢您的反馈。我附上了上面的网络代码。它从 FirebaseStorage 加载数据。我找不到 getData() 的异步函数。 编译失败的函数中weatherT是什么关系? 【参考方案1】:

本质上,如果您使用的 SDK 不支持并发 API,那么您可以使用它的唯一方法是调用 withCheckedContinuationwithCheckedThrowingContinuation(用于错误处理)。您的代码的问题要么是我提到的问题,要么是 Swift 没有从返回类型正确推断 T 类型的事实。 希望以下模式对您有用:

private func weatherDownload<T: Codable>(_ type: T.Type, weatherType: String) async throws -> T 
    return try await withCheckedThrowingContinuation  continuation in 
        // Your original code from before, 
        // with the following difference instead of calling the completion handler:
        ...
        do 
            let weather = try self.decoder.decode(T.self, from: data)
            continuation.resume(returning: weather)
         catch 
            continuation.resume(throwing: error)
        
    

有关此模式的更多信息,请查看以下链接:link1、link2

【讨论】:

感谢您提供这些信息。 withCheckedContinuation 正是我还不知道的。

以上是关于使用通用参数创建 async/await 函数的主要内容,如果未能解决你的问题,请参考以下文章

ES6 -async ,await

使用 es7 async/await 检查 mongodb 中是不是存在文档

async/await 面试题 加propmise

简单理解JavaScript 的async/await

fetch普通用法及搭配async,await用法小记

Node.js Promise对象(解决回调地狱问题)async和await函数