An introduction to Kotlin coroutines compared to Futures/Promises such as Reactor’s Mono or Java’s CompletableFuture Want to jump right into code? Go check it here . Introduction While reading about Kotlin's coroutines, I thought it would be really helpful to compare it to other async programming techniques, specifically the Futures/Promises approach that is widely used in Java. Even though the is pretty good and comprehensive, I felt the lack of a more “real world” example. This is an attempt to fill that gap. Kotlin documentation Do not expect to have a comprehensive view of how coroutines work nor how Java’s or Reactor’s work. CompletableFuture Mono The idea is to pick a quite simple made-up problem, implement it with the different approaches and libraries, and compare them. This is an introductory material to the topic. Now let’s get into the made-up problem. Problem Statement Who never needed to work on a problem where you need to get data from one place, do some processing and send it to a different place? The made-up problem here is basically that. Assume we work on e-commerce and we want to get the most recent order id from an HTTP endpoint, send this id to two other endpoints that: Give us the stock information about the items in the order, and; Give us the calculated delivery cost for the order. Then we need to expose all that information combined to other consumers. Let’s also assume that the operations after fetching the most recent order are slower on processing and we would like to run them in parallel. We would like to implement something like the following: Futures/Promises approach For the future/promises approach we will use two very popular APIs/libraries for dealing with Asynchronous Programming in Java: and . CompletableFuture Mono is available in the standard Java library since JDK 1.8 and got some improvements over the last releases. Because it is part of the standard library it is the default choice for Java libraries willing to support non-blocking processes and is used in some other APIs in standard libraries, like the . CompletableFuture java.net.HTTPClient is the equivalent in the library. Project Reactor is a quite popular non-blocking reactive library for the JVM. Its adoption has been growing recently, mostly because of its integration into Spring Framework. Mono CompletableFuture Project Reactor It has been adopted by other JVM libraries as well. Now let’s see how the implementation works with these libraries. First, an implementation using : CompletableFuture : CompletableFuture<CombinedResult> { orderIdFuture: CompletableFuture<String> = fetchMostRecentOrderId() orderIdFuture .thenCompose { orderId -> deliveryCostFuture: CompletableFuture<String> = fetchDeliveryCost(orderId) stockInformationFuture: CompletableFuture<String> = fetchStockInformation(orderId) deliveryCostFuture.thenCombine(stockInformationFuture) { r1, r2 -> CombinedResult(r1, r2) } } } : CompletableFuture<String> { ... } : CompletableFuture<String> { ... } fun completableFuture () val return val val fun fetchDeliveryCost () fun fetchStockInformation () Now the implementation: Mono : Mono<CombinedResult> { orderIdFuture: Mono<String> = fetchMostRecentOrderId() orderIdFuture .flatMap { orderId -> deliveryCostFuture: Mono<String> = fetchDeliveryCost(orderId) stockInformationFuture: Mono<String> = fetchStockInformation(orderId) deliveryCostFuture.zipWith(stockInformationFuture) { r1, r2 -> CombinedResult(r1, r2) } } } : Mono<String> { ... } : Mono<String> { ... } fun mono () val return val val fun fetchDeliveryCost () fun fetchStockInformation () They are quite similar, right? That’s exactly why they are here under the same section. They both follow the same async programming technique of Futures/Promises. You can see that the only difference (apart from the return type) are the methods used, even though they have exactly the same mechanics: / are used to compose two different promises, meaning basically “after this promise is completed, return this other promise”; thenCompose flatMap / are used to combine two different promises, meaning basically “give me a new promise that will complete after promises are completed”. thenCombine zipWith both We are not going into details of comparing both libraries, but, for basic use cases, you can see that they follow the same approach. Coroutines approach Kotlin coroutines are in essence lightweight threads. Kotlin language provides one high-level constructs, the , and one library, the library, in order to deal with asynchronous programming in a way that is very similar to the regular imperative programming most of the developers are used to. suspending functions kotlinx.coroutines Think of it as the Kotlin way of doing that is available in other languages such as C# or JavaScript. async/await Now, back to the topic. Here is how an implementation using suspending functions and constructs in library works: kotlinx.coroutines : CombinedResult = coroutineScope { orderId: String = fetchMostRecentOrderId() deliveryCostFuture: Deferred<String> = async { fetchDeliveryCost(orderId) } stockInformationFuture: Deferred<String> = async { fetchStockInformation(orderId) } CombinedResult(deliveryCostFuture.await(), stockInformationFuture.await()) } : String { ... } : String { ... } suspend fun coroutines () //Returns a String directly, no future object val //Note the Deferred type indicating this is a future val val //Awaiting for completion of previous parallel executed fuctions suspend fun fetchDeliveryCost () suspend fun fetchStockInformation () You can see it seems very similar to the imperative programming style most of us are used to and is how we learn coding in the first place. A few notes: All functions are functions, as seen by the keywords (lines 1, 13, 14). Suspending functions are basically the Kotlin way of in order to advise the compiler that it may run asynchronous operation; suspending suspend fun coloring a function Suspending functions can only be executed from within another suspending function or a ; coroutineScope builder Line 3 is suspended, meaning execution will be suspended (non-blocking!) waiting for the return of which returns a directly; fetchMostRecentOrderId String By using with a suspending function, we can run it on the background, which returns a Deferred object (that is like a promise) as seen in lines 6 and 7; async Line 10 is suspended again until the result of both Deferred objects complete, by calling the await function on the Deferred objects; We need to wrap the function into a coroutineScope in order to do parallel processing with async as coroutine code is executed . sequentially by default Kotlin’s answer to async/await is slightly different from that on JavaScript. For example, here would be a similar function in JS: { orderId = fetchMostRecentOrderId(); deliveryCostFuture = fetchDeliveryCost(orderId); stockInformationFuture = fetchStockInformation(orderId); CombinedResult( deliveryCostFuture, stockInformationFuture); } { ... } { ... } async ( ) function jsAsync const await //returns String const //returns Promise const //returns Promise return new await await async ( ) function fetchDeliveryCost async ( ) function fetchStockInformation The difference is subtle but important, while Kotlin coroutines are sequential by default, JavaScript ones are concurrent by default: On line 2 we need to use await, while in Kotlin there’s no need to do so; explicitly On lines 4 and 5 there’s no need to use any construct, as async functions in JS returns a Promise. async Conclusion This is quite a simple flow just to illustrate the differences in programming style/techniques. One could argue that for this specific example, the code is cleaner and simple to understand using the Futures/Promise approach, and it would be a matter of style. However, as the code grows more complex and we have more and more requirements things can get quite hard to manage with Futures/Promise. You can check for a good post with a more complex example comparing the two approaches. here Or even if we just get the same problem and just try to implement it sequentially things will get complicated with Futures/Promises. As seen , we needed to introduce intermediate types in order to share context, in this case by using . here Kotlin Pair type I’ve also put together a simple where you can run the code yourself and play around with the different techniques discussed here. Kotlin Spring Boot project This is a brief introduction to the topic and there is much more to get into the coroutines, for this, I would recommend the following material: The official Kotlin documentation on coroutines; from Kotlin documentation; The Asynchronous Programming Techniques page of the coroutines design document; The “Asynchronous programming styles” section Why are coroutines implementation are neither like JavaScript one nor like Go one? You can see why . here Thank you for reading until here and I hope you enjoyed it. I would like to give a huge thank you to the friends and colleagues who provided their kind words and early feedback on this post. You all rock! Previously published at https://medium.com/@danilo_barboza/kotlin-asynchronous-programming-styles-compared-347470b95f3a