async let and TaskGroup in Swift
Concurrency with async/await — Part 2
Let’s imagine we want to fetch several images, like this:
Looks simple right? But let’s run the app, and before that, let’s add some print statements to our fetchThumbnail(for id: String) async
:
And don’t forget to call the new function in the viewModel.onAppear()
.
Run the app! Here’s what we see in the console:
start 100
end 100
start 101
end 101
We may also notice that loading is pretty slow, and that’s because we get images one after the other, not in parallel.
How do we fix it? Actually, it’s easy with async let
. Add async
before let
in fetchThumbnails()
, and remove await
, and add try await
on the return
line:
Let’s run! What do we see now?
start 100
start 101
end 100
end 101
We get them in parallel! Basically, when we type async let
, we fire off the task, but we aren't waiting until it completes. We do it only when the variable is needed. In this case, on the return
line.
Task Groups
Now let's say we have an array of n
elements, let's actually say we want to fetch all images for our ids
array, that is located inside ThumnailRepositoryLive
.
How would you do it? Here's how I would do it:
Let’s run and see that images are downloaded one after another, once again!
That sucks! How do we fix it? async let
won't help us here (you can try 😉).
Let’s remove everything inside fetchThumbnails
, and add:
That gives us closure with group
, that we can use to add tasks, like here:
All we have to do is to await for them in a loop:
Now let’s run the app! What do we see now? The app is much faster! And have a look in the console — image downloading now happens in parallel!
We see each other in Part 3!