Deep look into Coroutine Suspend Functions. Part 3. Get result from suspend function.

Dmitry Pliskov
Axel Springer Tech
Published in
3 min readFeb 26, 2020

The series consists of 5 parts:

1. Suspend functions introduction
2. How does Continuation work
3. Get result from suspend function
4. How to create a suspend function
5. A small FAQ about suspend functions

In the previous part we discussed how suspend function is called from Continuation. Suspend function can return some value as a result of work. Let’s see how Continuation handles it.

In addition, I will add one more suspend function to show how switch operator divides the code.

Let’s have a look at this code:

The download function returns file that we use in the suspend function unzip.

In Continuation this code will be divided into the following three parts by the two suspend functions.

1) the download function and everything before it

2) the unzip function and everything between it and the download function

3) everything after the unzip function

The simplified Continuation code could look like this:

But it doesn’t work. Pay attention to passing the file from the download to the unzip function.

We are trying to get file this way:

But download is an asynchronous function. It starts to download file in the background thread and doesn’t return the file immediately as a result of the method call. Therefore, we cannot get file like this. We need to use another way to pass the result of suspend function to Continuation.

As we discussed in the previous article, when the suspend function is done, it calls the method invokeSuspend in Continuation. The suspend function passes the result of its work using this call. The method invokeSuspend has an input parameter for this purpose.

Continuation knows that the suspend function download passes the result here. Also, Continuation knows that label is 1 at the moment of this call. Therefore, Continuation casts parameter result to class File in the switch branch case 1.

The function download doesn’t return anything here. But when it’s done it will call invokeSuspend and pass the result there. This result is casted to the File class and used in the function unzip.

Let’s do this example a bit more complicated and add the return value for unzip. Now unzip returns the size of the unzipped package.

Let’s show this value in the toast after unzip is done:

Continuation code for this coroutine will be like this:

The mechanism is the same. When the function unzip is done it will call invokeSuspend and pass the result as Object. In case 2 branch the result is casted to Long and used in toast.

Conclusion

The method invokeSuspend calls suspend function, passes the Continuation and finishes current switch branch. When suspend function is done, it calls continuation.invokeSuspend and passes the result of work. Next switch branch is called in invokeSuspend. The result is casted to the needed type and used.

--

--