when to use "suspend function" vs "function return...
# coroutines
s
when to use "suspend function" vs "function returning Deferred"?
d
Never return Deferred. (There are use cases for returning Deferred, but if you have to ask, you don't have that use case)
šŸ‘šŸ¼ 1
ā˜ļø 8
ā˜šŸ¼ 2
šŸ‘ 3
c
Deferred
comes from the
async { }
builder, which is designed for spawning multiple parallel tasks and giving you a way to wait for them to finish and aggregate the results, A single function that would return a Deferred is essentially saying ā€œrun this function asynchronously and return a result`, which is exactly the same sentiment as a normal
suspend
function, but with an extra step. So donā€™t return
Deferred
, and generally, donā€™t use coroutine builders inside a function. Just mark the function suspend and wrap it in the appropriate coroutine builder at the call-site.
šŸ™ 2
āž• 1
s
generally, donā€™t use coroutine buildersĀ insideĀ a function
what is the reason behind this?
c
Because it prevents you from combining those functions, and will probably lead you to doing Very Bad Thingsā„¢ļø with those functions. This is what a code snippet might look like trying to combine functions that use builders internally:
Copy code
fun CoroutineScope.asyncMethod1(): Deferred<Int> = async {
    delay(1.seconds)
    1
}
fun CoroutineScope.asyncMethod2(someValue: Int) = launch {
    delay(1.seconds)
}
fun main() = runBlocking {
    val value1 = asyncMethod1().await()
    asyncMethod2(value1).join()

    println("finished")
}
and hereā€™s what it should look like:
Copy code
suspend fun asyncMethod1(): Int {
    delay(1.seconds)
    return 1
}
suspend fun asyncMethod2(someValue: Int) {
    delay(1.seconds)
}
fun main() = runBlocking {
    val value1 = asyncMethod1()
    asyncMethod2(value1)

    println("finished")
}
But like Dominic said above, there are use-cases for using coroutine builders inside the body of a function or returning a Deferred, but if you have to ask, then you donā€™t have that use-case
g
Itā€™s completely fine to use coroutine builders inside of a suspend function, if this function has own coroutine scope likeā€
Copy code
suspend fun doSomething() = coroutineScope {
   // here you can call any coroutine builders to run multiple coroutines in parallel, scope will return only when all those coroutines are finished
}
But using top level coroutine builder (and pass scope as argument of a function), is usually a bad solution
āž• 2