Consider the following (silly) example:
func u () async -> UInt32 {
let r = UInt32(Int.random(in: 1...10))
sleep(r)
return r
}
func v(_ x: UInt32) -> UInt32 {
x
}
Task.init{
print(v(await u()))
print(await v(u()))
await print(v(u()))
}
All three lines in the task appear to work. Are they equivalent, or are there any pitfalls I should be aware of? Thanks.
>Solution :
Like try, Swift allows you to place the await keyword on any part of an expression that contains an async method:
func ƒ<T>(_ v: T) -> T { v }
// All equivalent:
func somethingThatThrows() throws {}
print(ƒ(try somethingThatThrows()))
print(try ƒ(somethingThatThrows()))
try print(ƒ(somethingThatThrows()))
// All equivalent:
func someAsyncFunc() async {}
Task {
print(ƒ(await someAsyncFunc()))
print(await ƒ(someAsyncFunc()))
await print(ƒ(someAsyncFunc()))
}
The Swift grammar reference for the await keyword does have an example for where placement of await does matter (awaiting only a subexpression of a whole expression that needs to be awaited), but it’s not quite relevant here:
// await applies to both function calls
sum = await someAsyncFunction() + anotherAsyncFunction()
// await applies to both function calls
sum = await (someAsyncFunction() + anotherAsyncFunction())
// Error: await applies only to the first function call
sum = (await someAsyncFunction()) + anotherAsyncFunction()