【问题标题】:How I can return value from async block in swift如何快速从异步块返回值
【发布时间】:2019-02-16 15:53:12
【问题描述】:

请看下面的代码:

backgroundthread.async {
    return self.mycallback() //return string, int etc
}

我想从异步块中返回一个值。我不想要任何完成处理程序或任何其他解决方法。

func getAppConfigFromDB(_ key: String) -> String 
{
   let value = String()
   backgroundthread.async {
      let inst = AppConfigDB.init(_APP_CONFIG_DB_PATH)
      value = inst.getConfigurationInfo(key) // I want to return from here.
   }
   return value
}


getAppConfigFromDB("path")

【问题讨论】:

  • 您别无选择,只能使用完成处理程序。您不能从异步调用中返回值。
  • 好的,有什么变通方法或自定义模板,我们可以使用。
  • 我同意@rmaddy,完成处理程序是异步任务完成时处理结果的唯一方法。他们给它起了个好名字!
  • 为什么要避免使用完成处理程序?您试图解决什么问题,而由于某种原因需要避免最简单和适当的解决方案?
  • 这里和 Swift API 中有无数的例子。

标签: swift multithreading


【解决方案1】:

就像@rmaddy 所说,除了使用完成处理程序之外别无他法。

func getAppConfigFromDB(_ key: String, completion: @escaping ((String) -> Void)) {
    let value = String()
    backgroundthread.async {
        let inst = AppConfigDB.init(_APP_CONFIG_DB_PATH)
        value = inst.getConfigurationInfo(key) // I want to return from here.
        completion(value)
    }
}

你这样调用方法。

getAppConfigFromDB("") { (value) in
    // Use value to do something
}

【讨论】:

    【解决方案2】:

    你的函数需要像这样的闭包

    func getAppConfigFromDB(_ key: String, completion: @escaping (String?) -> Void) {
        backgroundthread.async {
            completion("string here")
        }    
    }
    

    当你调用你的函数时,你会这样做

    getAppConfigFromDB("key") { (returnedString) in
        //returnedString is Optional("string here")
    }
    

    【讨论】:

      【解决方案3】:

      您用return self.mycallback() 描述的内容类似于

      打字稿:

      String text = await someTask();
      

      或在 C# 中:

      String text = someTask().result;
      

      并且来自异步函数:

      String text = await someTask();
      

      然而,这个概念在 swift 中并不存在(我认为 Java 也是如此)。

      除了使用完成处理程序之外,我能想到的唯一其他方法是将结果传递给另一个函数(注意:如果您打算在主线程/UI 线程上工作,您将遇到异常 - 您需要像这样把你的电话放在DispatchQueue.main.async {/*Do stuff...*/})中

          func startAsync {
              let url = URL(string: "https://jsonplaceholder.typicode.com/todos/1")!
              let task = URLSession.shared.dataTask(with: url) {(data, response, error) in
                  guard let data = data else { return }
                  guard let jsonString = String(data: data, encoding: .utf8) else { return }
                  DispatchQueue.main.async {
                      self.setResults(text: jsonString);
                  }
              }
              task.resume()
          }
      
          func setResults(text: String?){
              textView.text = text;
          }
      

      完整项目: https://github.com/AppLogics/SwiftAsyncTaskWithoutCompletionHandler

      【讨论】:

        猜你喜欢
        • 2021-08-22
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-04-08
        • 2017-10-24
        • 1970-01-01
        相关资源
        最近更新 更多