简体   繁体   中英

How I can return value from async block in swift

Please have a look into the code below:

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

I want to return a value from an async block. I don't want any completion handler or any other workaround.

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")

Like @rmaddy said, you have no other way than to use completion handlers.

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)
    }
}

You call the method like this.

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

Your function would need a closure like so

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

When you call your function you would do

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

What you are describing with return self.mycallback() is something like in

TypeScript:

String text = await someTask();

or in C#:

String text = someTask().result;

and from an async function:

String text = await someTask();

However this concept does not exist in swift (and i think Java too).

The only other method I can think of other than using a completion handler, is passing the results to another function (NOTE: If you intend on working on the main thread/UI Thread you will get an exception - you will need to wrap your call in DispatchQueue.main.async {/*Do stuff...*/} ) like so

    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;
    }

full project: https://github.com/AppLogics/SwiftAsyncTaskWithoutCompletionHandler

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM