lets say you want to apply something to the result...
# getting-started
x
lets say you want to apply something to the result of a completable future in a coroutine, but only after the completable future finishes and you don't want to explicitly await it, how would you do it?
so, from your service layer you call your API client, but you want your API client to, for example, convert the API response to something else
but you dont want to await in the API client, because you might have multiple requests in your service layer and want to launch them simultaneously and await them as they are needed
(like flatmapping on a mono)
j
Do you mean literally
CompletableFuture
- the Java one? Is your client exposing suspend functions to the service layer?
Note that it's the whole point of suspend functions to be written sequentially and yet still have asynchronous execution. So awaiting the future and returning a transformed value is exactly what you should do. If the service layer wants to call multiple things concurrently, it expresses it with
async
x
interesting, so you're not supposed to return monos from your API client
but instead explicitly await on them
j
Exactly. I mean at least if you're really using coroutines. Overall it would look like this:
Copy code
class Client {
    suspend fun fetchThing1(): TransformedThing1 {
        val rawValue1 = doTheAsyncThing1().await()
        return transformSomehow(rawValue1)
    }
    suspend fun fetchThing2(): TransformedThing2 {
        val rawValue2 = doTheAsyncThing2().await()
        return transformSomehow(rawValue2)
    }
}

class Service(val client: Client) {
    suspend fun doStuffWithBoth(): CombinedThing = coroutineScope {
        // making both calls concurrently
        val thing1 = async { client.fetchThing1() }
        val thing1 = async { client.fetchThing2() }
        combineBothResultsIntoASingleThing(thing1.await(), thing2.await())
    }
}
👍 1
x
@Joffrey forgot to respond, this was super helpful, thanks!
😊 1