Whenever we need to write asynchronous code we tend to use callbacks which allow us to trigger an action and, instead of waiting for it to finish, get notified through the callback for the action’s completion. Coroutines change that and help us write asynchronous code but in a sequential way.
This means that instead of writing code like this:
we can write it like this:
But what do we do when there is no easy way to remove callbacks from existing code or when we use a third party library that is not coroutines ready? This is where suspendCoroutine
comes to save the day.
suspendCoroutine
suspendCoroutine
is a function that does exactly what is says. It suspends the coroutine that it was called from and provides a way to resume it.
Lets have an example. The code here:
simply prints 1 2 3 4 Done!. If we change it to:
it will print 1 2 3 and then it will just wait. We suspended the coroutine but we did not resume it. To do so we will use the continuation instance that suspendCoroutine
provides:
now it prints 1 2 3 … 4 Done!. The coroutine printed the first three numbers, got suspended, while being suspended another block of code got executed and printed the dots and then resumed the coroutine allowing it to print the final number and done.
Continuation adapter
Back to our first example. Lets say that downloadTasks
cannot be changed. We still need to call it and provide a callback for its results.
What we need to do is to suspend the coroutine, call downloadTasks
to.. well.. download the tasks and provide a callback that upon completion it will resume the coroutine with the tasks at hand.
To achieve that we first need to create an adapter that will connect the callback with a continuation:
and then call suspendCoroutine
:
That’s it. The adapter resumes the coroutine by providing the tasks that are then returned to the suspension point.
One more thing
Along side suspendCoroutine
there is also suspendCancellableCoroutine
which provides a cancellable continuation. That means that in addition of resuming we can also execute code upon cancellation:
this will print Downloading… and then Cancelled…