Colton Idle
04/30/2020, 8:29 PMviewModelScope.launch {
val nameResponse = retrofitService.getName()
val phoneResponse = retrofitService.getPhone()
print("${nameResponse.isSuccessful.toString()} ${phoneResponse.isSuccessful.toString()}")
}
Is making it parallel as easy as doing this?
viewModelScope.launch {
val nameResponse = async { retrofitService.getName() }
val phoneResponse = async { retrofitService.getPhone() }
print("${nameResponse.await().isSuccessful.toString()} ${phoneResponse.await().isSuccessful.toString()}")
}
If that is all I need. Am I missing something anything from your point of view. Besides error handling (which is a whole other topic)? Any other ways to do this?octylFractal
04/30/2020, 8:30 PMasync
, in which case you should wrap that whole block with coroutineScope {}
Colton Idle
04/30/2020, 8:32 PMviewModelScope.launch {
//my code here
}
octylFractal
04/30/2020, 8:32 PMColton Idle
04/30/2020, 8:32 PMColton Idle
04/30/2020, 8:34 PMoctylFractal
04/30/2020, 8:35 PMretrofitService.getName()
isn't suspending and can block for long enough to consider it not-good for the view thread, you should async(<http://Dispatchers.IO|Dispatchers.IO>)
insteadoctylFractal
04/30/2020, 8:35 PMoctylFractal
04/30/2020, 8:37 PMasync(Dispatchers.Default)
is actually the correct thing. obviously the IO dispatcher is just for IO (disk/network/etc.)Colton Idle
04/30/2020, 8:37 PMoctylFractal
04/30/2020, 8:37 PMColton Idle
04/30/2020, 8:39 PMoctylFractal
04/30/2020, 8:40 PMasync
allows access to the value at a later point. withContext
is just another way to (1) switch dispatchers, and (2) open up a new CoroutineScope like I suggested with coroutineScope {}
Colton Idle
04/30/2020, 8:47 PMColton Idle
04/30/2020, 8:48 PMColton Idle
04/30/2020, 8:48 PMsuspend fun getNameAndPhone() = withContext(<http://Dispatchers.IO|Dispatchers.IO>) {
// withContext waits for all children coroutines
launch { retrofitService.getName() }
launch { retrofitService.getPhone() }
}
octylFractal
04/30/2020, 8:49 PMoctylFractal
04/30/2020, 8:49 PMColton Idle
04/30/2020, 8:49 PMviewModelScope.launch {
//Call in parralel
val nameRes = async { retrofitService.getName() }
val phoneRes = async { retrofitService.getPhone() }
//Wait for both to be done
print("${nameRes.await().isSuccessful.toString()} ${phoneRes.await().isSuccessful.toString()}")
}
octylFractal
04/30/2020, 8:51 PMsuspend fun getNameAndPhone() = coroutineScope {
val nameRes = async { retrofitService.getName() }
val phoneRes = async { retrofitService.getPhone() }
return@corountineScope nameRes.await() to phoneRes.await()
}
which would get you a Pair<Name, Phone>
(or whatever the type is)Colton Idle
04/30/2020, 8:52 PMoctylFractal
04/30/2020, 8:53 PMoctylFractal
04/30/2020, 8:53 PMCoroutineScope.launch
, CoroutineScope.produce
, Flow.launchIn
, CoroutineScope.actor
, etc.Colton Idle
04/30/2020, 8:53 PMEyeCon
05/02/2020, 5:15 PMEyeCon
05/02/2020, 5:16 PMoctylFractal
05/02/2020, 5:18 PMEyeCon
05/02/2020, 8:59 PMfor
on a channel for example. But for lambdas and such, this is a quick way to see what exactly is suspending.