The Monster
09/08/2021, 7:52 PMreturn webservice.getAllFacts()
.also {
coroutineScope {
launch {
catFactDao.insertAllFacts(it)
}
}
}
Code compiles, but is it a bad idea to use scope function on the return value (does it block even with the coroutine?)The Monster
09/08/2021, 7:53 PMval list: List<CatFact> = webservice.getAllFacts()
coroutineScope {
launch {
catFactDao.insertAllFacts(list)
}
}
return listThe Monster
09/08/2021, 8:01 PMsuspend function must be stopped when that function returns
https://developer.android.com/kotlin/coroutines/coroutines-adv#parallelJoffrey
09/08/2021, 10:49 PMcoroutineScope { launch { suspendCall() }} is equivalent to just suspendCall() , because coroutineScope waits for its child coroutines to finish before returningJoffrey
09/08/2021, 10:51 PMThe Monster
09/08/2021, 11:26 PMlist while leaving the IO task (insert the list into DB) running by itself. The coroutine techniques I tried, like Dispatchers.IO for example, are still blocking the method from returning. the only way that worked was to create a new Thread.
suspend fun getAllFacts(): List<CatFact> { //TODO return Flow<List<CatFact>> instead
if (allFactsLoaded) {
return catFactDao.selectAllFacts()
} else {
val list: List<CatFact> = webservice.getAllFacts()
//thread(start = true) {
// catFactDao.insertAllFacts(list)
//}
catFactDao.insertAllFacts(list)
return list
}
}
I am still reading the coroutines docs to see if there is anything else I can try.Joffrey
09/08/2021, 11:32 PMgetAllFacts either as argument or more conventionally as receiver (although we're already breaking conventions anyway 😄 ).
So your function could look like this:
suspend fun CoroutineScope.getAllFacts(): List<CatFact> {
if (allFactsLoaded) {
return catFactDao.selectAllFacts()
} else {
val list: List<CatFact> = webservice.getAllFacts()
launch {
catFactDao.insertAllFacts(list)
}
return list
}
}
You could also just have the scope somewhere in the class that declares this function, and simply use it to launch the coroutine:
suspend fun getAllFacts(): List<CatFact> {
if (allFactsLoaded) {
return catFactDao.selectAllFacts()
} else {
val list: List<CatFact> = webservice.getAllFacts()
someScope.launch {
catFactDao.insertAllFacts(list)
}
return list
}
}Joffrey
09/08/2021, 11:35 PMThe Monster
09/09/2021, 12:13 AMcoroutineScope { launch { suspendCall() }} is useless because there is no non-returning code outside of the coroutineScope AND there is only one launch call? I swear I saw code written like this in the docs, but now I read it again, the call outside of the coroutineScope is a println() lol.Joffrey
09/09/2021, 12:19 AMcoroutineScope suspends until all child coroutines are done, but if there is just one and no code running concurrently with it (inside coroutineScope), there is no point. It's like doing async { suspendCall() }.await() - starting a coroutine and immediately waiting for itJoffrey
09/09/2021, 12:20 AMcoroutineScope {
launch { suspendCall() }
somethingElse()
}
is ok because suspendCall and somethingElse will run concurrentlyThe Monster
09/09/2021, 12:21 AMprivate val scope: CoroutineScope = CoroutineScope(EmptyCoroutineContext)
I am glad that you said using the outer coroutine breaks convention, which aligns with the Android docs from Google. I will take some more time to process your statements because I am quite a beginner in coroutines.The Monster
09/09/2021, 12:24 AMJoffrey
09/09/2021, 12:29 AM