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.
CodePudding user response:
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 (await
ing only a subexpression of a whole expression that needs to be await
ed), 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()