Hi all :android-wave: , A couple of questions rega...
# coroutines
a
Hi all 👋 , A couple of questions regarding this code. 1. Is this correct? 2. Any way to improvise this code?
Copy code
private suspend fun getData(): MyData {
        return coroutineScope {
            val data1 = async(
                context = dispatcherProvider.io,
            ) {
                getData1UseCase()
            }
            val data2 = async(
                context = dispatcherProvider.io,
            ) {
                getData2UseCase()
            }
            val data3 = async(
                context = dispatcherProvider.io,
            ) {
                getData3UseCase()
            }

            MyData(
                data1 = data1.await(),
                data2 = data2.await(),
                data3 = data3.await(),
            )
        }
    }
getData1UseCase()
-> Returns a list of
Data1
type.
getData2UseCase()
-> Returns a list of
Data2
type.
getData3UseCase()
-> Returns a list of
Data3
type. I want to fetch all the data in parallel. So, using
async
for each use case call.
k
Looks okay to me
👌 1
If you really wanted to, you could:
Copy code
suspend fun foo() {
  return withContext(<http://dispatcherProvider.io|dispatcherProvider.io>) {
    val first = async { ... }
    val second = async { ... }
    return MyData(first.await(), second.await())
  }
}
👍 1
g
If you already have a dependency on Arrow, you could also use its parZip function: suspend fun getUser(id: UserId): User = parZip( { getUserName(id) }, { getAvatar(id) } ) { name, avatar -> User(name, avatar) }
today i learned 2
u
Bit late, but I have a small improvement for you. You can use
awaitAll
to fail faster, when one of the tasks fail.
awaitAll
will cancel the first tasks (and all others) as soon as one of the later fail. Otherwise it’s the same:
Copy code
val (data1, data2, data3) = awaitAll(
                async(
                    context = dispatcherProvider.io,
                ) {
                    getData2UseCase()
                }, 
                async(
                    context = dispatcherProvider.io,
                ) {
                    getData2UseCase()
                },
                async(
                    context = dispatcherProvider.io,
                ) {
                    getData2UseCase()
                }
            )
    MyData(data1, data2, data3)
👍 2
K 2
a
Oh nice, I was actually using await all, but I changed from that as it was returning a list and I had to type cast the result. I didn't think about destructuring. Thanks for sharing this. @uli .
👍 1