https://kotlinlang.org logo
Title
a

asad.awadia

11/27/2018, 12:49 AM
How to
await
for completion of a suspending function that wraps a blocking call with
withContext
b

bdawg.io

11/27/2018, 3:09 AM
withContext
itself returns the result, so there's no need to await. If you are wanting to execute the
withContext
concurrently, use
async
instead
val result = withContext(<http://Dispatchers.IO|Dispatchers.IO>) { blockingCall() }
vs
val resultAsync = async(<http://Dispatchers.IO|Dispatchers.IO>) { blockingCall() }
doSomethingElse()
val result = resultAsync.await()
a

asad.awadia

11/27/2018, 3:17 AM
How do I create a suspending function then? Given a blocking call?
g

gildor

11/27/2018, 3:24 AM
what do you mean?
see: imagine, you have
fun myApiBlockingCall(): String {
  Thread.sleep(1000)
  return "Foo"
}
To convert it to non-blocking using withContext:
suspend fun myApiCall() = withContext(IO) {
   myApiBlockingCall()
}
And that’s all. You can call myApiCall in any suspend block with any dispatcher without blocking
a

asad.awadia

11/27/2018, 1:06 PM
@gildor but now how do I await the result?
I can’t do
myApiCall().await()
right - how do I wait for the result?
g

gildor

11/27/2018, 1:17 PM
You don't need await for suspend functions, just call
myApiCall()
a

asad.awadia

11/27/2018, 1:49 PM
How would that work if i m calling it from main? It would just fall through and exit right
l

louiscad

11/27/2018, 1:51 PM
@asad.awadia
suspend fun main()
(new in 1.3) can directly call this suspending function
a

asad.awadia

11/27/2018, 1:52 PM
Yeah i read
Let me try it
Whaaaaaa
This is some magic right here
Thank you guys
How do i ‘return’ foo from the suspend function
It complains i need another return statement outside the with context
l

louiscad

11/27/2018, 2:00 PM
The magic you're talking about is similar to
fun main() = runBlocking(Dispatchers.Default) { … }
fun main()
needs to return
Unit
, be it
suspend
or not
a

asad.awadia

11/27/2018, 2:06 PM
No no main
How do i assign value of myApiCall to a var
MyApiCall - i can add a return inside the with context - but intellij complains that i need one at the end too
l

louiscad

11/27/2018, 2:09 PM
Maybe you're looking for
return@something
?
a

asad.awadia

11/27/2018, 2:13 PM
Yeah that’s inside the with context
But apparently the function itself needs a return outside too
l

louiscad

11/27/2018, 2:20 PM
Yes, you need to return result of
withContext
call
a

asad.awadia

11/27/2018, 4:10 PM
I ll post a code snippet after work to show what I mean
g

gildor

11/27/2018, 4:15 PM
withContext is just a function with lambda param. For any real application you probably need not a suspend main, but some coroutine builder, like
launch
as entry point for your async coroutines code
I would also recommend to use runBlocking instead of suspend main. It may be handy sometimes, but runBlocking also provides CoroutineScope, so you can use launch or async directly and don't worry about running coroutines
a

asad.awadia

11/27/2018, 4:18 PM
Would you prefer launch async over suspend functions?
I thought async await is discouraged
g

gildor

11/27/2018, 4:19 PM
No, I prefer suspend functions and suspend functions also recommended by official guide
But to use suspend functions you need suspend lambda, so you need to somehow start coroutine, so use launch, async or runBlocking
I'm talking only about entry point usage, that to play with coroutines in
main
method is more handy to use
fun main() = runBlocking<Unit>{}
instead of
suspend fun main() {}
because runBlocking also provides coroutine scope
a

asad.awadia

11/27/2018, 4:24 PM
Oh ok ok
I see makes sense
Thank you!
l

louiscad

11/27/2018, 6:08 PM
Or you can use
coroutineScope { … }
in
suspend fun main()