WWDC21 introduces Swift 5.5, with async/await. Following the Explore structured concurrency in Swift and Meet async/await in Swift WWDC21 sessions, I'm trying to use the async let function.
Here's my Playground code:
func doIt() async -> String {
let t = TimeInterval.random(in: 0.25 ... 2.0)
Thread.sleep(forTimeInterval: t)
return String("\(Double.random(in: 0...1000))")
}
async {
async let a = doIt()
async let b = doIt()
async let c = doIt()
async let d = doIt()
let results = await [a, b, c, d]
for result in results {
print(" \(result)")
}
}
However, for each of the "async let" lines, I get this error:
error: AsyncLetSwift55WWDC21.playground:12:15: error: expression is 'async' but is not marked with 'await'
async let a = doIt()
^
await
Paul Hudson's blog showed this example:
The Exploring structured currency video has this example at about the 8:10 mark:
EDIT: This does seem to be a Playground-specific issue. Per the suggestion on the same issue in Apple Developer Forums, running the same code (ok, I did add sleep(10)
to the end of the source file after the async block for macOS, so the app wouldn't terminate before the async calls completed) as a macOS command-line project gives no errors and produces the proper output.
Is this a bug, or am I just not understanding something?
Swift now supports asynchronous functions — a pattern commonly known as async/await. Discover how the new syntax can make your code easier to read and understand. Learn what happens when a function suspends, and find out how to adapt existing completion handlers to asynchronous functions.
Calling an asynchronous function with await runs only one piece of code at a time. While the asynchronous code is running, the caller waits for that code to finish before moving on to run the next line of code.
Because await is only valid inside async functions and modules, which themselves are asynchronous and return promises, the await expression never blocks the main thread and only defers execution of code that actually depends on the result, i.e. anything after the await expression.
Although Swift functions are synchronous by default, we can make them asynchronous by adding one keyword: async . Inside asynchronous functions, we can call other asynchronous functions using a second keyword: await . As a result, you'll often hear Swift developers talk about async/await as a way of coding.
My advice would be: don't try this in a playground. Playgrounds aren't ready for this stuff yet. Your code compiles and runs fine in a real project. Here's an example:
class ViewController: UIViewController {
func doIt() async -> String {
let t = TimeInterval.random(in: 0.25 ... 2.0)
Thread.sleep(forTimeInterval: t)
return String("\(Double.random(in: 0...1000))")
}
func test() {
async {
async let a = doIt()
async let b = doIt()
async let c = doIt()
async let d = doIt()
let results = await [a, b, c, d]
for result in results {
print(" \(result)")
}
}
}
override func viewDidLoad() {
super.viewDidLoad()
test()
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With