A journey from callback hell to Kotlin coroutines, Episode 1
Ahmed is a developer, who loves spending his spare time reading e-books. One day, he opened a pdf download app, started searching for some books, then started downloading, suddenly the app started to lag, then the UI became irresponsive, then BAM, the app crashed.
Users may be annoyed of such an experience, and may delete the app from their devices.
There are many reasons of the aforementioned case to happen, the one we are considering here is Threading.
As an up-to-date android developer, Ahmed didn’t want this scenario to happen with his app users. So, he made some research, and found that, app needs to move any long-running code from the main thread
As mentioned in Android Developer official site:
If the main thread cannot finish executing blocks of work within 16ms, the user may observe hitching, lagging, or a lack of UI responsiveness to input. If the main thread blocks for approximately five seconds, the system displays the Application Not Responding (ANR) dialog, allowing the user to close the app directly.
OK, now, Ahmed knew the cause, and continued to use his researching skills, to know what options he can use to write asynchronous code, and found some solutions like:
- Futures, Promises
- Reactive Extensions (Rx)
A thread in computer science is short for a thread of execution. Threads are a way for a program to divide (termed “split”) itself into two or more simultaneously (or pseudo-simultaneously) running tasks.
Threads is a good solution, but has some concerns,
In computer programming, a callback, also known as a “call-after” function, is any executable code that is passed as an argument to other code; that other code is expected to call back (execute) the argument at a given time. This execution may be immediate as in a synchronous callback, or it might happen at a later point in time as in an asynchronous callback.
He found it useful as well, until he ran into a code like this:
The above GIF shows what’s known as callback hell, when there are too many nested callbacks, the code becomes difficult to read, also difficult to handle exception and debug.
I promise I will return at some point in the future
Besides debugging and error handling challenges, Promises needs further work after getting data is returned, because it returns a promise of Data, so we need more lines of code to get our model from that promise :( .
Reactive Extensions (Rx)
Everything is a stream, and it’s observable
Rx is awesome, but it introduces new concepts that Ahmed needs to learn, instead, He decided to find a solution that can be implemented with the same framework and language he uses (Kotlin in our example), so. he moved forward to find something better.
Kotlin’s approach to working with asynchronous code.
From the above code and chart Ahmed found that, he only needs to add suspend keyword before the function and it becomes thread safe, he can then use it the same way he was calling the function that made the problem :D, without changing the return type, or introducing new concepts, or depending on a specific platform.
Unlike threads, coroutines are lightweight, non-expensive, making it possible to use multiple coroutines in the same thread. also easy yo switch between threads. It also can be stopped, relaunched, or cancelled.
Ahmed was happy with coroutines, but wanted to test it with some examples to make sure they deserve the switch, He then opened his IDE, but after a lot of work, he felt sleepy 🥱, so he decided to have a break and take a nap, then continue practicing after being refreshed.
See you in the next episode after Ahmed wakes up 👋.