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?
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()
}
}
Building as a macOS command line project (Xcode: File -> New -> Project, then select "Command Line Tool" from the macOS tab), the code works perfectly. (This was a suggestion from a response in the Apple Developer Forums .)
I've added a single sleep(10)
to the end so that the command line tool doesn't exit before the async calls finish:
import Foundation
print("Hello, world!")
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)")
}
}
sleep(10)
This produces the expected sort of console output (Note: the actual values will differ on every run)*:
Hello, World!
415.407747869283
574.28639828183
689.4706625185836
385.56539085197113
Program ended with exit code: 0
It runs well as macOS command line project, but when I created it as a iOS project,
Those codes:
async let a = doIt()
async let b = doIt()
async let c = doIt()
async let d = doIt()
DO NOT runs in parallel.
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.