[swift-evolution] async void

Adam Kemp adam_kemp at apple.com
Thu Nov 9 15:45:17 CST 2017


> On Nov 9, 2017, at 11:02 AM, Wallacy <wallacyf at gmail.com> wrote:
> 
> So for me, this:
> 
> func OnButtonClicked(_ sender:AnyObject) {
>     let button = sender as! UIButton
>     button.isEnabled = false
>     beginAsync {
>         await DoSomethingAsync()
>         button.isEnabled = true
>     }
> }
> 
> Does not make any sense... Because await will not block the thread we can assume (like the exemple on proposal) that compiler will actually do the same what we will do using GDC and pick everyone to until the context ends and encapsulate as completion handle to the away call.

I don’t understand what you’re saying here. In terms of GCD the above code is basically equivalent to this:

func buttonClicked(_ sender:AnyObject) {
    let button = sender as! UIButton
    button.isEnabled = false
    doSomethingAsync { // completion callback, assume it’s on the main queue
        button.isEnabled = true
    }
}

> And this one:
> 
> @IBAction func buttonDidClick(sender:AnyObject) {
>   beginAsync {
>     let image = await processImageData()
>     // Do the update on the main thread/queue since it owns imageView.
>     mainQ.async {
>       imageView.image = image
>     }
>   }
> }
> 
> 
> Does not make any sense too.
> 
> The only way to await to do not block the thread is make a early return like beginAsync and encapsulate as completion handle the rest of the code. 

This is why “await” can only be used in a function that is marked as “async”. The “async” keyword tells the compiler that this function will be broken up into parts, and its return value will be produced asynchronously.

One thing that might be confusing is that in the examples using “beginAsync” the trailing closure is the async function. That’s not obvious because there’s no “async” keyword, but it’s there in the signature of the closure argument:

func beginAsync(_ body: () async throws -> Void) rethrows -> Void

I’m not sure how the proposed design handles type checking for async closures. Is async part of the type? Can I declare a local closure variable as async? What are the rules for conversion between async and non-async closures? Is it a warning or error to use a closure literal without an async keyword that is assigned to an async closure variable or passed as an async closure argument?

C# dodges all of these issues because async isn't part of the type system. Closures that don’t return anything can be declared async just like void functions, and code that uses void-returning closures doesn’t need to care whether the implementation is async or not.

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.swift.org/pipermail/swift-evolution/attachments/20171109/4def2a1b/attachment.html>


More information about the swift-evolution mailing list