Let me know if there is better way :arrow_heading_...
# coroutines
d
Let me know if there is better way ⤴️
Hmm that’s interesting approach. So, e.g. my typical android code would look like this:
Copy code
val job = Job()
fun loadData() = job.launch(UI) {
    val result = withContext(CommonPool) { ... }
    view.showResult(result)
}
But, if I want to launch another coroutine how I can achieve that, in case if
async
require job receiver?
Copy code
val job = Job()
fun loadData() = job.launch(UI) {
    // val result = async(CommonPool) { ... }.await()  can't do that, async require job receiver
    val result = job.async(CommonPool) { ... }.await() // this one is correct?
    view.showResult(result)
}
v
e.g. my typical android code would look like this
Empty jobs are not recommended, it doesn’t really make sense. Job should be bond with either your Android activity or another job.
But, if I want to launch another coroutine how I can achieve that
async
builder itself will have job (or something similar to it) as receiver, so nested async will work as expected:
Copy code
val loadData() = job.launch(UI) {
   val innerTask = async(CommonPool) {}
   // Here inner task implicitly inherits job of UI activity and will be cancelled when activity is destroyed
}
d
Empty jobs are not recommended, it doesn’t really make sense.
I have made empty job to cancel it in activity
onDestroy
function. (because lifecycle aware stuff is available from library only, it’s not part of android sdk). With lifecycle callback it will look like in your sample
lifecycle.job().launch(UI)
.
Btw, it should not affect context switching right?
withContext
will stay the same correct?
v
Thanks for clarification, then your example is fine.
withContext
will stay correct, but this part of design is not yet properly investigated. Probably
withContext
should have job as well
d
If
withContext
need job as well, it would require write more code. E.g. currently in http client
Copy code
fun loadUser(id: String, 
                       context: CoroutineContext = CommonPool) = withContext(context) {
    // logic
}
With new design:
Copy code
fun loadUser(id: String, context: CoroutineContext = CommonPool, job: Job) 
= job.withContext(context) {
    // logic
}
I will have to pass job everywhere, am I right?
v
In such cases (when no one can cancel your task) you can use
Eternal
.
Copy code
fun loadUser(id: String, context: CoroutineContext) = Eternal.withContext(context) {
    // logic
}
or maybe we can try to inherit job from given context (though it’s debatable approach)
d
Doesn't a suspend fun have a coroutineContext...? withContext will only work in suspend fun...