I know that we wait with await
and execute a task without need to wait with async let
, but I can't understand the difference between these two calls:
async let resultA = myAsyncFunc()
async let resultB = await myAsyncFunc()
In my experiment, both of these seem to behave exactly the same, and the await
keyword does not have any effects here, but I'm afraid I'm missing something.
Thanks in advance for explanation on this. đđ»
I'm adding a working sample so you can see the behavior
func myAsyncFuncA() async -> String {
print("A start")
try? await Task.sleep(for: .seconds(6))
return "A"
}
func myAsyncFuncB() async -> String {
print("B start")
try? await Task.sleep(for: .seconds(3))
return "B"
}
async let resultA = myAsyncFuncA()
async let resultB = await myAsyncFuncB()
print("Both have been triggered")
await print(resultA, resultB)
Results:
A start // Immediately
B start // Immediately
Both have been triggered // Immediately
A B // After 6 seconds
So as you can see, resultA
does not block the context and the total waiting time is the biggest waiting time.
You asked what is the âdifference between âasync letâ and âasync let awaitââ. There is none.
The await
is unnecessary at this point and is generally omitted. One can argue that in async let x = await âŠ
declaration, the await
would best be omitted, to avoid confusion, because it does not actually await
at that point.
So, the behavior you outline in your revision to your question is correct.
async let resultA = myAsyncFuncA() // execution of this current task is not suspended
async let resultB = await myAsyncFuncB() // execution is also not suspended here
print("Both have been triggered") // we can see this before the above two child tasks finish
await print(resultA, resultB) // only here is this task suspended, awaiting those two child tasks
When resultA
and resultB
are declared with async let
, the respective asynchronous child tasks will be created, but the current task will not be suspended (notably, despite the await
in async let resultB = await âŠ
). Execution of the current task continue to proceed to the subsequent lines, after those two initializations, while A and B run concurrently. Execution will not actually await the results until you hit the await
on the fourth line, the await print(âŠ)
. The await
in the second line, where you async let resultB = await âŠ
, does not actually await it.
In SE-0317 â async let
bindings, they say that the âinitializer of a async let
permits the omission of the await
keywordâ. Describing this as âpermitsâ is an understatement; we practically always omit the await
at the point of initialization.