In Part1 we have discussed synchronous code , asynchronous code, what was the need of async / await when we were already having async method calling available, with example.
Reference of Part1 — https://medium.com/@amitaswal87/async-await-in-swift-part-1-6c5f58162bb2
Now in Part2, we will discuss how Pyramid of Doom issue was resolved by Async / Await.
How to use Async/Await to avoid Pyramid of doom
Imagine that we need to execute a sequence of simple asynchronous operations which always requires deeply-nested closures, like imagine that you need to download an image, then resize it, decode it and finally upload it and notify when its done
func processImage(from url: URL, completion: @escaping (Bool) -> ()) {
downloadImage(from: url) { image in
convertToPdf(image: image) { pdf in
decode(image: pdf) { decodedImage in
resize(image: pdf) { response
completion(response.sccuess)
}
}
}
}
}
Now lets see how with the introduction of Async / Await life become easier.
func processImage(from url: URL) async -> Bool{
let image = await downloadImage(from: url)
let resizedImage = await decode(image: image)
let response = await resize(image: resizedImage)
return response.isSccuess
}
When we start by downloading an image using the downloadImage
function, which is asynchronous, we need to use await
. The await
keyword suspends the execution of our code while it waits for the downloadImage
function to complete and return a result.
During this suspension, other parts of our program can continue to run concurrently. For instance, a long-running background task might keep updating a list of new photo galleries. This background task will run until it reaches its own suspension point, indicated by another await
, or until it finishes.
Once the downloadImage
function completes and returns, our code resumes execution from the point where it was suspended. The returned value from downloadImage
is assigned to the image
variable.
Next, the code reaches another await
in the call to the convertToPdf(image:)
function. The execution pauses again until this function returns, allowing other concurrent code to run in the meantime.
After convertToPdf(image:)
completes, the code resumes execution from that point and assigns the returned value to the pdf
variable.
This process continues for any subsequent asynchronous functions until all the async tasks have completed and the final result is returned.
The suspension points marked with await
indicate where your code might pause while waiting for an asynchronous function to complete. During these pauses, Swift can run other code on the current thread, making efficient use of resources. Because await
can suspend execution, you can only call asynchronous functions or methods from specific places in your program that can handle these suspensions.
You can download the sample code foe API handler using Async/Await from here
This is how Pyramid of Doom can be escaped using Async / Await.
We can call multiple async methods in parallel also using async/await. Lets check it out in Part3 — https://medium.com/@amitaswal87/async-await-in-swift-part3-4692987034fe